Cpp skrócenie kodu, zmiana części na rekuręcję | Dzielenie wielomianu przez dwumian


(Antonizelazo) #1

Jeśli stopień wielomianu wejściowego oznaczymy jako n, to na wejściu otrzymasz jeden wiersz tekstu zawierający rozdzielone spacjami n+2 liczby rzeczywiste; n+1 pierwszych liczba to współczynniki dzielnej, ostatnia to wyraz wolny dzielnika; 4 ≤ n ≤ 102

 

Wyjście to jeden wiersz, zawierający jedną liczbę rzeczywistą równą reszcie z dzielenia wielomianu przez dwumian

#include <iostream>
#include <string>
#include <cstdio>
using namespace std;
int main(){
	string a,b,d;
	getline(cin,a);
	int c,e,z,f;
	int y=1;
	for(int i=0;i<a.size();i++){
		if(a[i]==32)c=i;
	}
	c++;
	d.insert(0,a,c,a.size()-1);
	sscanf(d.c_str(),"%d",&e);
	e=-e;
	for(int i=0;i<c;i++){
	if(a[i]!=32)b+=a[i];
		else{
			sscanf(b.c_str(),"%d",&f);
			if(y==1)z=f;else
			z=z*e+f;b="";y=0;
		}
	}
	cout<<z;
}

Po usunięciu wszystkich tabulacji oraz enterów jego waga nadal przekracza 350B. Chciałbym go skrócić jeszcze bardziej, a mianowicie poniżej 300B.

Wydaje mi się że mógłbym to osiągnąć gdybym urzył rekuręcji ale niestety nigdy czegoś takiego nie robiłęm.

Mógłby mi ktoś zmodyfikować ten kod tak aby ważył poniżej 300B albo chociaż podpowiedział jak bym mógł taki efekt osiągnąć?


(enedil) #2

Taki kod

int main(){std::string a,b,d;getline(std::cin,a);int i,c,e,z,f,y;for(i=0;i<a.size();i++)if(a[i]==32)c=i;c++;d.insert(0,a,c,a.size()-1);e=atoi(d.c_str());for(i=0;i<c;i++)if(a[i]!=32)b+=a[i];else{f=atoi(b.c_str());(y!=1)?z=f:z=z*e+f;b="";y=1;}std::cout<<z;}

działa i ma 255 bajtów. Kompilacja odbywa się poprzez

g++ -include "iostream" -include "string" -include "cstdlib" file.cpp -o file

(pio_95) #3

Taka uwaga - kolejne wersje kodu dają - dla tych samych danych wejściowych - inne wyniki, niż pierwsza, pewnie gdzieś wkradł się błąd.

int i=0,...
for(;ia.size();++i)...

zawsze to jeden znak mniej :wink:

c++;d.insert(0,a,c,a.size()-1);
// można zmienić na
d.insert(0,a,++c,a.size()-1);

Edit:

e=-e;
-e;

Te dwie linie nie są jednoznaczne, (przynajmniej w C++ 4.9.2 testowanym na ideone, jeśli gdzie indziej to działa, niech mnie ktoś poprawi)

(y!=1) ? z=f : z=z*-e+f;

Edit2: ok, jedziemy dalej:

//for(i=0;ia.size();i++)
//	if(a[i]==32)c=i;
c=a.find_last_of(' '); 

Edit3: użycie przecinków zamiast średników pozwala wyeliminować nawiasy klamrowe po else:

{f=atoi(b.c_str());(y!=1)?z=f:z=z*-e+f;b="";y=1;}
f=atoi(b.c_str()),(y!=1)?z=f:z=z*-e+f,b="",y=1;

Edit4: Dlaczego insert na początek pustego ciągu, a nie metoda substr? String d staje się niepotrzebną zmienną.

#include iostream
#include string
#include cstdlib
int main(){
	std::string a,b;
	getline(std::cin,a);
	int i=0,c,e,z,f,y=0;
	c=a.find_last_of(32);
	e=atoi(a.substr(++c).c_str());
	for(;ic;i++)
		if(a[i]!=32)
			b+=a[i];
		else
			f=atoi(b.c_str()),
			(y!=1)?z=f:z=z*-e+f,
			b="",y=1;
	std::coutz;
}

tj. po usunięciu tabulatorów i znaków nowej linii 38 znaków mniej, niż @enedil

276 bajtów razem z nagłówkami.

Mam nadzieję, że niczego nie spaprałem.

 

I jeszcze jedno - w opisie zadania masz, że na wejściu liczby rzeczywiste, a cały program na intach :stuck_out_tongue:


(Antonizelazo) #4

kurna napisałem na forum a potem o tym zapomniałem…

Dzięki wszystkim za pomoc.

Też do tego doszedłem że pracuje na intach a nie na rzeczywistych.

Oto co wypracowałem przez noc:

#include<iostream>
int main()
{
	double t[105],e,z;
	int n=1;
	int i,y;
	std::cin>>t[n-1];
	while(std::cin.get()!='\n') {
		std::cin>>t[n];
		n++;
    }
    n--;
    e=-t[n];
    for(i=0;i<n;i++){
    	(y!=1) ? z=t[i] : z=z*e+t[i];
    	y=1;
    }
	printf("%.3lf", z);
}

Wszystko działa… przynajmniej u mnie… A wolałbym aby działało wszędzie. Chodzi o to że nie wiem czemu ale na http://ideone.com ciągle przekracza mi limit czasu. Nie wiecie czemu??


(pio_95) #5

Szukanie tego kolejnego znaku do wyciśnięcia to całkiem niezła zabawa.


(Antonizelazo) #6

Do czego służy getchar()?


(dorion300) #7

http://pl.wikibooks.org/wiki/C/getchar