Optymalizacja programu.

0

Witam skończyłem mój program który pobiera z jednego pliku liczby i rozklada je na liczby pierwsze.
Wymysliłem cos takiego:Pobieram ciag z pliku getlinem,sprawdzam czy to jest na pewno liczba,jak jest to liczba to wykonuje działanie,jak nie jest to liczba wypisuje błąd,ale sam kod wydaje mi sie dziwny i troche przekombinowany dodatkowo mam jeden problem chciałbym,zeby po zmianie danych wejsciowych i ponownym odpaleniu programu liczby w pliku 2 sie zamienialy,a nie dopisywały,ale jak nie dam app to program zle dziala. I jeszcze prosze ,bo nie moge znaleŹĆ linka jak zrobic zeby ten program mogl byc odpalony z lini polecen.

 #include <iostream>
#include <fstream>
#include <conio.h>
#include <string>
#include <cstdlib>
#include <sstream>
using namespace std;

void zapisdo2( string plik2, const char* k )
{
    fstream plikos;
    plikos.open( "plik2.txt", ios::out | ios::app );
    plikos << k;

}

void zapisdo( string plik2, int k )
{
    fstream pliko;
    pliko.open( "plik2.txt", ios::out | ios::app );
    pliko << k<<" ";
    pliko.close();
}

void rozklad( int x ) // rozklad na czyyniki
{
    string plik2;
    const char* s="\n";
    int k = 2;
    while( x > 1 )
    {
        while( x % k == 0 )
        {
            zapisdo( plik2, k );
            x /= k;
        }
        ++k;
    }
  zapisdo2(plik2,s);

}

void odczytpliku( string plik1 )
{
    string plik2;
    fstream plik;
    string linia;
    int z;
    plik.open( "plik1.txt", ios::in );
    if( plik.good() )
    {
        while( getline( plik, linia ) )
        {
              z = 0;
        int x = 0;
            for( unsigned int i = 0; i < linia.length(); i++ )
            {
                if( !isdigit( linia[i] ) )
                {
                    z = 1;
                }
            }
            if( z != 1 )
            {
                istringstream iss( linia );
                iss>> x;
                rozklad( x );

            }
            else
            {
                const char* k = "blad wprowadzenia\n";
                zapisdo2( plik2, k );
            }
        }
    }
    else
        cout << "nie udalo sie wczytac";
        plik.close();
}

int main()
{
    string plik1;
    odczytpliku( plik1 );
    return 0;
}
 
0

Linia poleceń:

int main(int argc, char *argv[])
{
	for(int i = 0; i < argc; ++i)
	{
		printf("arg[%i] = %s\n", i, argv[i]);
		 // lub: cout << "arg[" << i << "] = " << argv[i] << endl;
	}
}
0

I to bedzie do pliku wejsciowego i wyjsciowego?I jak tego uzyje to mam zmieniac cos np w

 plikos.open( "plik2.txt", ios::out | ios::app );

?

0

I do tego bym jakies warunki chciał porobic,przyda sie jakis fajny poradnik.

0

to jak przyda sie jakis fajny poradnik (jak sam zauwazyles) to zapraszam na google.com

0

Ok,a powiecie mi czy program jest bardzo zle zoptymalizowany?czy nie ma za duzo zmiennych?I czy da sie zrobic tak,ze po kazdym otworzeniu pliku wczesniejsze dane sie wymazuja?Bo jak nie dam app to wtedy nie dziala program...

0

jezeli chodzi o optymalizacje to

  1. nigdy nie optymalizuj jezeli to nie jest koniecznie (sa wyjatki od tego ale watpie zeby do Ciebie aplikowaly)
  2. jezeli porzebujesz uzyj profilera i zobacz gdzie jest problem. Jak zobacyzsz gdzie jest problem to wtedy go popraw

jezeli chodzi o "duzych zmiennych" to

  1. Twoj program nie jest czytelny. Zmienne sa nieodpowiednio nazwane (powinny miec wartosc w nazwie zeby czytajacy wiedzial co to jest ta zmienna)
  2. brak formatowania
  3. nazwy funkcji zapisdo2. Zadna zmienna ani funkcja nie powinna miec liczb zawartych w nazwie, bo przewaznie to jest kopia tego co juz robi i wystarczy to cos rozszerzyc odpowiednio, lub to jest calkowicie osobna metoda i powinna sie inaczej nazywac

Tak jak pisalem wystarczy googlowac jezeli chodzi o flagi
http://en.cppreference.com/w/cpp/io/ios_base/openmode

0

Wlasnie próbowalem te flagi i jak uzywam trunca,ate i samego outa program nie dziala..

0

Odnosnie wiersza polecen to znalazlem cos takiego:

 char *plikotw=0;
char *plikzap=0;
if(argc==1)
{cout<<"nie podales plikow;
}
else
{
char*stringotwarcia="-o";
char*stingzapisu="-i";
for(int i;i<argc;++i)
{
if(!strcmp(argv[i],stringotwarca)
{plikootw=argv[i+1]
}
else if(!strcmp(argv[i],stringzapisu)
{
plikzap=argv[i+1]
}
if(!plikotw)
cout<<"nie podano pliku otw";
 

teraz chce to wrzucic pod maina,przed funkcja void?I co wpisac tam gdzie wpisywalem nazwy plikow?te stringi co teraz mam do wiersza polecen?
To by było nawet dla mnie logiczne ,ze to ma tak wygladac ale wole sie upewnic.I potem jak mam taki plik odpalic?bo widzialem ze kolega raz wrzucal plik exe do cmd,a niektorzy pisza ze wystarczy sama nazwa.

0

Jeszcze jedna poważna wada, jak masz nie użyte prze funkcje parametry - to masz błąd konceptualny (owszem są wyjątki ale jeszcze nie ten poziom).
Co do optymalizacji, owszem przedwczesna optymalizacja jest złem, ale w przypadku kiedy wersja zoptymalizowana jest krótsza od niezoptymalizowanej to zawsze wybieraj tą zoptymalizowaną.
Jako przykład, ten twój problem można zrobić w ten sposób:

#include <iostream>
#include <fstream>
#include <vector>
#include <cmath>
using namespace std;
 
vector<unsigned> Eratostenes(size_t max)
  {
   vector<bool> tb(++max,true);
   vector<unsigned> ret;
   for(size_t sq=4,i=2;sq<=max;sq+=i,sq+=(++i)) 
     {
      if(tb[i])
        {
         for(size_t k=i*i;k<max;k+=i) tb[k]=false;
         ret.push_back(i);
        }
     }
   return ret;
  }

void factorization(const vector<unsigned> &tb,unsigned value)
  {
   cout<<value<<" =";
   unsigned shift=2;
   for(unsigned i=0,div=tb[i];div<=value;)
     {
      unsigned next=value/div;
      if(value-next*div) div=tb[++i];
      else
        {
         cout<<(" * "+shift)<<div;
         value=next;
         shift=0;
        }
     }
   if(value!=1) cout<<(" * "+shift)<<value;
  }

void proceed(ifstream &fin)
  {
   unsigned max=0,value;
   while(fin)
     {
      if(!(fin>>value)) fin.clear();
      else if(max<value) max=value;
      while((fin.get()!='\n')&&(fin)) {}
     }
   vector<unsigned> tb(Eratostenes((unsigned)sqrt(max)));
   fin.clear();
   fin.seekg(0,ios::beg);
   while(fin)
     {
      if(!(fin>>value)) fin.clear();
      else factorization(tb,value);
      for(int ch;((ch=fin.get())!='\n')&&(fin);) cout.put(ch);
      cout<<endl;
     }
  }

int main(int argc,char *argv[])
  {
   ifstream fin(argc<2?"test.txt":argv[1]); // jak nie podasz pliku do odczytu to czyta z test.txt
   if(!fin)
     {
      cerr<<"Nie udalo sie otworzyc pliku"<<endl;
      return 1;
     }
   ofstream fout;
   if(argc>2) // jak nie podasz pliku do zapisu to wywala na ekran
     {
      fout.open(argv[2]);
      cout.rdbuf(fout.rdbuf());
     }   
   proceed(fin);
   return 0;
  }

Tak dla porównania wpisz do pliku jakieś 1000 razy liczbę 174636000

Łatwizna: wpisujesz raz 174636000<Enter>, po czym 10 razy powtarzasz <Ctrl-A><Ctrl-C><Ctrl-V><Ctrl-V>
i odpal swoją wersje oraz moją :D

0

Musze pozostać przy mojej wersji i na razie jestem na takim poziome,ze niektóre błędy mogą przejść.Dobrze myśle z tym wierszem polecen?

1
divider212 napisał(a):

Musze pozostać przy mojej wersji i na razie jestem na takim poziome,ze niektóre błędy mogą przejść.
Rozumiem, zwyczajnie nie chcesz się uczyć.

divider212 napisał(a):

Dobrze myśle z tym wierszem polecen?
Nie.
Nie potrzebujesz "-i" i "-o" ponieważ masz tylko te dwa parametry więc zawsze możesz przyjąć że pierwszy to plik wejściowy zaś drugi wyjściowy. Możesz zwyczajnie sprawdzić czy jest dwa parametry i po krzyku.
Lub zobacz jak zrobiłem to w moim przykładzie, jak to zadziała - w komentarzach opisano.

0

Chce sie uczyć,ale jestem gdzieś na początku,a mam zadanie gdzie jest wymagane to "-i" i "-o" i maja byc podane w dowolnej kolejności.Tylko nie wiem jak zapisać te fstringi()Co ma byc w srodku?

2
divider212 napisał(a):

Chce sie uczyć ...
JAk nawet nie podjąłeś próby zrozumienia i dopasowania? Chrzani waść.

#include <cstring>
#include <iostream>
using namespace std;

int main(int argc,char *argv[])
  {
   const char *opt[][2]={{"-i"},{"-o"}};
   const size_t optsize=sizeof(opt)/sizeof(*opt);
   for(int i=1;i<argc;++i)
     {
      const char *par=argv[i];
      for(int k=0;k<optsize;++k)
        {
         int len=strlen(opt[k][0]);
         if(!strncmp(par,opt[k][0],len))
           {
            if(argv[i][len]) opt[k][1]=argv[i]+len;
            else if(++i<argc) opt[k][1]=argv[i];
            break;
           }
        }
     }
   if(opt[0][1]) cout<<"odczyt z \""<<opt[0][1]<<'"'<<endl;
   else cout<<"nie podano pliku do odczyt"<<endl;
   if(opt[1][1]) cout<<"zapis do \""<<opt[1][1]<<'"'<<endl;
   else cout<<"nie podano pliku do zapisu"<<endl;
   return 0;
  }

można podawać jako -i plik.txt lub też jako -iplik.txt

0
pliko.open( "plik2.txt", ios::out | ios::app ); 

to co wtedy ma sie znajdywać w tej linijce?

1

Po głupiemu:

pliko.open(PrzekazanaNazwaPliku,ios::out|ios::app);

Po mądremu: otwierasz plik w main, do funkcji przekazujesz referencje na ostream.

0

Jak robie po głupiemy(referencji jeszcze nie miałem)

void zapisdo2( string plikzapisywany, const char* k )
{
    fstream plikos;
    plikos.open( plikzapisywany,ios::out|ios::app );
    plikos << k;

}

error: no matching function for call to 'std::basic_fstream<char>::open(std::string*&, std::_Ios_Openmode)'|
Jedyne co mi przychodzi do głowy to w tym voidzie cos zmienic,ale nie mam pomysłu co.

1

jedno z:
1.

void zapisdo2(const string &plikzapisywany,const char* k)
  {
   fstream plikos(plikzapisywany.c_str(),ios::out|ios::app);
   plikos<<k; 
  }
void zapisdo2(const char *plikzapisywany,const char* k)
  {
   fstream plikos(plikzapisywany,ios::out|ios::app );
   plikos<<k; 
  }

1 użytkowników online, w tym zalogowanych: 0, gości: 1