Zamiana liczb na slowa /c++ dlaczego wyświetla tylko początek słów

0
#include <iostream>
#include <stdio.h>

using namespace std;

int main()
{

    string jednosci[10] = { "", " jeden", " dwa", " trzy", " cztery", " piec", " szesc", " siedem", " osiem", " dziewiec" };
    string nascie[10] = { "dziesiec", " jedenascie", " dwanascie", " trzynascie", " czternascie", " pietnascie", " szesnascie", " siedemnascie", " osiemnascie", " dziewietnascie" };
    string dziesiatki[10] = { "", " dziesiec", " dwadziescia", " trzydziesci", " czterdziesci", " piecdziesiat", " szescdziesiat", " siedemdziesiat", " osiemdziesiat", " dziewiecdziesiat" };
    string setki[10] = { "", " sto", " dwiescie", " trzysta", " czterysta", " piecset", " szescset", " siedemset", " osiemset", " dziewiecset" };

    string slownie = " ";
    long int liczba;
    int koncowka;
    int rzad = 0;
    int j = 0;
    int minus = 0;

    cout << "Podaj liczbe:";
    cin >> liczba;

    if (liczba < 0) {
        minus = 1;
        liczba = -liczba;
    }

    if (liczba == 0)
        slownie = "zero";

    while (liczba > 0) {
        koncowka = (liczba % 10);
        liczba /= 10;

        if ((j == 0) && (liczba % 10 != 1))
            slownie = jednosci[koncowka];
        if ((j == 0) && (liczba % 10 == 1)) {
            slownie = nascie[koncowka];
            liczba /= 10;
            j += 2;
            continue;
        }
        if (j == 1)
            slownie = dziesiatki[koncowka];
        if (j == 2) {
            slownie = setki[koncowka];
            j = -1;
            rzad++;
        }
        j++;
    }

    if (minus == 1)
        slownie = "minus";

    cout << "Odp:" << slownie;
} 
0

Kiedyś pisałem coś takiego. Nie jest to ideał, ale możesz zerknąć na pomysł.

#include <array>
#include <string>

namespace my {
    enum class VariantMagnitude : int { SINGLE = 1, ATYPICAL, NORMAL };
    
    template <class Type>
    class IntToStr {

    public:
        IntToStr() = default;

        IntToStr(Type number) : number_{ number }, numAsText_{ L"" }
        { convertToText(number_); }

        IntToStr(const IntToStr& other) = delete;

        IntToStr(IntToStr&& other) = delete;

        std::wstring convertToText(Type number) {
            int magnitudeOfNum = designateMagnitudeOfNum(number);
            std::wstring sign = designateSignOfNum(number);
            number = abs(number);
            for (int actualMagnitude{}; actualMagnitude <= magnitudeOfNum; ++actualMagnitude) {
                Type groupOfMagnitude = number % 1000;
                std::wstring units = unitsToText(groupOfMagnitude % 100);
                std::wstring tens = tensToText(groupOfMagnitude % 100);
                std::wstring hundreds = hundredsToText(groupOfMagnitude / 100);
                numAsText_ = hundreds + tens + units + magnitudeToText(actualMagnitude, groupOfMagnitude) + numAsText_;
                number /= 1000;
            }
            numAsText_ = sign + numAsText_;
            return numAsText_;
        }

        Type getNumber() const {
            return number_;
        }

        std::wstring getNumberAsText() const {
            return numAsText_;
        }   

    private:
        Type number_;
        std::wstring numAsText_;

        std::wstring designateSignOfNum(Type number) {
            return number < 0 ? L"minus " : L"";
        }

        int designateMagnitudeOfNum(Type number) {
            int magnitudeOfNum{};
            while (number / 1000) {
                ++magnitudeOfNum;
                number /= 1000;
            }
            return magnitudeOfNum;
        }

        VariantMagnitude checkVariantMagnitude(Type group) {
            if (group % 100 == 1)
                return VariantMagnitude::SINGLE;
            else if (group % 10 > 1 && group % 10 < 5 && group % 100 != 12 && group % 100 != 13 && group % 100 != 14)
                return VariantMagnitude::ATYPICAL;
            else
                return VariantMagnitude::NORMAL;
        }

        std::wstring magnitudeToText(int magnitude, Type group) {
            std::array<std::wstring, 13> magnitudes{ 
                L"", L"tysiąć ", L"tysiące ", L"tysięcy ", L"milion ", L"miliony ", L"milionów ",
                L"miliard ", L"miliardy ", L"miliardów ", L"bilion ", L"biliony ", L"bilionów " };
            if (magnitude > 4)
                return L"Nieznany rząd wielkości ";
            return magnitude ? magnitudes[((magnitude - 1) * 3) + static_cast<int>(checkVariantMagnitude(group))] : magnitudes[0];
        }

        std::wstring unitsToText(Type firstHundred) {
            std::array<std::wstring, 10> units{ 
                L"", L"jeden ", L"dwa ", L"trzy ", L"cztery ", L"pięć ", L"sześć ", 
                L"siedem ", L"osiem ", L"dziewięć " };
            if (firstHundred / 10 == 1)
                return units[0];
            else
                return units[firstHundred % 10];
        }

        std::wstring tensToText(Type firstHundred) {
            std::array<std::wstring, 10> dozens{ 
                L"dziesięć ", L"jedenaście ", L"dwanaście ", L"trzynaście ", L"czternaście ", 
                L"piętnaście ", L"szesnaście ", L"siedemnaście ", L"osiemnaście ", L"dziewiętnaście " };
            std::array<std::wstring, 10> tens{
                L"", L"", L"dwadzieścia ", L"trzydzieści ", L"czterdzieści ", L"pięćdziesiąt ", 
                L"sześćdziesiąt ", L"siedemdziesiąt ", L"osiemdziesiąt ", L"dziewięćdziesiąt " };
            if (firstHundred / 10 == 1)
                return dozens[firstHundred % 10];
            else
                return tens[firstHundred / 10];
        }

        std::wstring hundredsToText(int numberOfHundred) {
            std::array<std::wstring, 10> hundreds{ 
                L"", L"sto ", L"dwieście ", L"trzysta ",L"czterysta ", L"pięćset ", 
                L"sześćset ", L"siedemset ", L"osiemset ", L"dziewięćset " };
            if (numberOfHundred < hundreds.size())
                return hundreds[numberOfHundred];
        }
    };
} 
0

dlaczego wyświetla tylko początek słów

A dlaczego nie miałoby, zważywszy że zamiast sklejać stringi za każdym razem podmieniasz wynik?

slownie = jednosci[koncowka];

Kiedyś pisałem coś takiego. Nie jest to ideał, ale możesz zerknąć na pomysł.

Nie chce mi się sprawdzać poprawności, ale ten kod jest przekombinowany i ze dwa razy za długi.

0

Skończony kod.Tylko mam pytanie .korzystałem z algorytmu już dostępnego w sieci modyfikująć .czy powinienem ,czy będe musiał sam je wymyślać?

 #include <iostream>
#include <stdio.h>

using namespace std;

int main()
{
    cout<<"\\\\\\Zamiana liczb na slowa///\n";

string jednosci[10] = {"", " jeden", " dwa", " trzy", " cztery", " piec", " szesc", " siedem", " osiem", " dziewiec"};
string nascie[10] = {"dziesiec", " jedenascie", " dwanascie", " trzynascie", " czternascie", " pietnascie", " szesnascie", " siedemnascie", " osiemnascie", " dziewietnascie"};
string dziesiatki[10] ={"", " dziesiec", " dwadziescia", " trzydziesci", " czterdziesci", " piecdziesiat", " szescdziesiat", " siedemdziesiat", " osiemdziesiat", " dziewiecdziesiat"};
string setki[10] = {"", " sto", " dwiescie", " trzysta", " czterysta", " piecset", " szescset", " siedemset", " osiemset", " dziewiecset"};
string duze[6] = {"", " tys.", " mln.", " mld.", " bln.", " bld."};

string      slownie = " ",powtorzyc;
long long        liczba;
int     koncowka;
int     rzad = 0;
int     j = 0;
int    Minus = 0;
cout<<1000000 %10;

do{
cout<<"Podaj liczbe:";
cin>>liczba;

if (liczba<0)
{
Minus=1;
liczba=-liczba;
}

if (liczba==0) slownie="zero";

while (liczba>0)
{
koncowka=(liczba%10);
liczba/=10;
if ((j==0)&&(liczba%100!=0 || koncowka!=0)) slownie=duze[rzad]+slownie;
if ((j==0)&&(liczba%10!=1)) slownie=jednosci[koncowka]+slownie;
if ((j==0)&&(liczba%10==1))
{
slownie=nascie[koncowka];
liczba/=10;
j+=2;
continue;
}
if (j==1) slownie=dziesiatki[koncowka]+slownie;
if (j==2)
{
slownie=setki[koncowka]+slownie;
j=-1;
rzad++;
}
j++;
}

if (Minus==1) slownie="minus"+slownie;

cout<<"Odp:"<<slownie;
cout<<"    |||Powtorzyc ? [wpisz tak]\n";
cin>>powtorzyc;

   rzad = 0;
   j = 0;
   Minus = 0;
   slownie = " ";

}while(powtorzyc=="tak");

return 0;
}
0

Tylko mam pytanie .korzystałem z algorytmu już dostępnego w sieci odpowiednio go modyfikująć .czy powinienem ,czy będe musiał sam je wymyśląć, prawdą jest że informatycy w pracy wymyślają algorytmy czy korzystają już z kiedyś wymyślonych?

0

A po co wymyślać koło na nowo? Jak coś jest dostępne, to należy używać.

0

Ja mam taki kod na wypisywanie liczb:

 
void ntostr(double fl, char *s)
{
  char str[20];
  char *j[] = {"","jeden","dwa","trzy","cztery","piec","szesc","siedem","osiem","dziewiec"},
       *jn[]= {"dziesiec","jede",j[2],j[3],"czter","piet","szes",j[7],j[8],"dziewiet"},
       *Rz[]= {"bilion","miliard","milion","tysi"};
  char i, k, p, a, b, c;


  sprintf(str, "%15.0f", fl); if( strlen(str) > 15 ) return;
  for(i = 0; i < 15 && str[i] == ' '; i++) str[i] = '0';
  s[0] = 0;
  if( str[i] == '-' ) { strcat(s, "minus "); str[i] = '0'; }

  for(k = 0; k < 5; k++)
   {
      i = k*3;
      a = str[i]-'0'; b = str[i+1]-'0'; c = str[i+2]-'0';
      for(p = 0; p < 3; p++)
       {
          if( p == 0 )
           {
             if( a == 1 ) strcat(s, "sto ");
             else if( a == 2 ) strcat(s, "dwiescie ");
             else if( a > 2 ) { strcat(s, j[a]); strcat(s,(a < 5 ? "sta " : "set ")); }
           }
          else if( p == 1 )
           {
             if( b == 1 ) { strcat(s, jn[c]); strcat(s, (c ? "nascie " : " ")); break; }
             else if( b ) { strcat(s, j[b]); strcat(s, (b == 2 ? "dziescia " : (b<5?"dziesci ": "dziesiat "))); }
           }
          else if( c ) { strcat(s, j[c]); strcat(s, " "); }
       }

      if( k < 4 && ( a || b || c) )
       {
          strcat(s, Rz[k]);
          a = (c == 1 && !a && !b);
          b = (c > 1 && c < 5 && b != 1);
          if( k == 3 ) strcat(s,(b ? "ace " : (a ? "ac " : "ecy ")));
          else strcat(s,(b ? "y " : (a ? " " : "ow ")));
       }
   }
}
0

Tutaj w miarę proste rozwiązanie bez żadnych wygibasów. Niestety aby zwiększać ilość obsługiwanych liczb należy wszystkie je, wpisywać ręcznie.
Przykład jednak może być prostszy do zrozumienia:

#include <iostream>
#include <cstdlib>

static const char *number_words[][11]={
	{"jeden","dwa","trzy","cztery","piec",
	 "szesc","siedem","osiem","dziewiec"},

	{"","dwadziescia","trzydziesci","czterdziesci","piecdziesiat",
	"szescdziesiat","siedemdziesiat","osiemdziesiat","dziewiecdziesiat"},

	{"sto","dwiescie","trzysta","czterysta","piecset","szescset",
	"siedemset","osiemset","dziewiecset"},

	{"tysiac","dwa tysiace","trzy tysiace","cztery tysiace","piec tysiecy",
	"szesc tysiecy","siedem tysiecy","osiem tysiecy","dziwiec tysiecy"}
};

static const char *number_teen[][11]={
        {"dziesiec","jedenascie","dwanascie","trzynascie","czternascie",
        "pietnascie","szesnascie","siedemnascie","osiemnascie","dziewietnascie"}	
};

static const int max_number = 10000;
static const int max_digits = 4+1;

int main(int argc,char **argv){
	using namespace std;

	unsigned int number;
	if(argc < 2)
		cin >> number;
	else
		number = atoi(argv[1]);

	if(number == 0)return 0;		//number is non zero
	number %= max_number;			//max number
	
	int multi = 0,digits = max_digits;
	for(multi=max_number;!(number/multi);multi/=10,--digits);	//how many digits?
	
	for(int i = digits;(i >= 0) && number;--i){
		if((number>=10) && (number<20)){			//teen numbers
			cout << number_teen[0][number%10] << " ";
			break;
		}else if(number / multi){				//other numbers
			cout << number_words[i-1][number/multi-1] << " ";
		}
		number %= multi;
		multi /= 10;
	}
	cout << endl;
	return 0;
}
 

Oraz test czy wszystko gra (sprawdzałem do 1100):

perl -e 'for($i=0;$i<10000;$i++){print `./NumbersToText $i`;};' 
0

Wszystko od 10000-20000 -tych liczb nie zamienia mi prawidlowo.i kilku innych przypadków

0

Tzn ten program obsługuje liczby do 10 000. Masz podane w kodzie programu. Jakich innych przypadków?

Algorytmy należy stosować jeżeli tylko są dostępne i pewne. Dobrze opisany algorytm wymaga jednak od dobrego programisty zrozumienia, aby nie popełnić różnych gaf w programie. Do algorytmów znalezionych w pół-pewnych źródłach tj. internecie (a nie w książkach uznanych autorów), trzeba mieć ograniczone zaufanie.

Podałem ten przykład, abyś mógł zobaczyć, że można stworzyć coś w bardzo prosty sposób (wydaje mi się, że nie jest to zbyt skomplikowane). Ten sposób rozwiązania problemu ma pewne zalety i wady. Algorytm jest prosty dla przypadków liczb powiedzmy w przedziale od 1-1000, ale czym większy zakres tym Twój nakład pracy nad programem będzie większy.
Wniosek:
Musisz wybierać algorytmy najlepszy, w danym momencie, dla Twojego programu, ale mieć także na uwadze to, że gdy program przejdzie modyfikację, bardzo prawdopodobne będzie to, że będziesz musiał dostosować algorytmy występujące w Twoim programie.

Rzadko kiedy zdarza się "algorytm uniwersalny".
Do tego warto abyś poczytał o wzorcach projektowych. Często widzę w programach dziwne algorytmiczne rozwiązania, które można zamienić na inną strukturę programu (wzorzec projektowy), co daje nam większy porządek, wprowadza standaryzację do Twojego kodu, kod lepiej się czyta oraz program jest mniej wrażliwy na zmiany.
"Praktyka buduje teorię, nigdy odwrotnie."

0

Kiedyś pisałem coś takiego. Nie jest to ideał, ale możesz zerknąć na pomysł.

Nie chce mi się sprawdzać poprawności, ale ten kod jest przekombinowany i ze dwa razy za długi.</quote>

Może i nie jest krótki, ale jest w miarę prosty i uwzględnia polską odmianę.

0

chwila chwila program poprawnie działa nawet przy bilionach tylko problem siępojawia jak wpisujenp. 1000000 albo 100001

przy 20000 juz nie ma problemu to bardzo dziwne ...a skąd mam brać algorytmy?

0

...a skąd mam brać algorytmy?

Ten nie jest taki trudny, więc samemu można go napisać. Pisz po kawałku i debuggerem sprawdzaj stan zmiennych.
Tak najszybciej załapiesz co w trawie piszczy.

edit: trochę na skróty napisałem:

  • napisz fragment kodu (który da się skompilować i uruchomić).
  • ustaw breakpointy w miejscach, w których chcesz podejrzeć stan zmiennych.
  • lub przeglądaj linia po linii.
    Instrukcje korzystania z debuggera do twojego środowiska, możesz znaleźć na stronie wydawcy.
0

tak tylko się pytam bo wszscy odsyłają do dokumentacji

Bo na forum uzyskasz wskazówki, gdy program nie działa właściwie (problem programistyczny),
natomiast znajomości narzędzi nikt nie będzie cię uczył. Od tego jest dokumentacja.

0

"dobrze może do czegoś się przyda ten debuging ale wątpie" - perełka

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