[c] Zamiana słowa na liczbę

0

Chcę zamienić słowo na liczbę.
Dla przykładu:

Sample Input

six
negative seven hundred twenty nine
one million one hundred one

Sample Output

6
-729
1000101

Napisałem kod który oddziela wpisane liczby.
Nie wiem teraz jak je porównywać, czy szukać w tablicy, czy jest jakiś inny sposób na to.

Oto mój kod:

#include <stdio.h>
#include <stdlib.h>

int main()
{

    char * slowo[] = {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten",
"eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen",
"twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety", "hundred",
"thousand", "million"};
    int liczba[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,30,40,50,60,70,80,90,100,1000,1000000};

    char n[]="";
    int i=0;

    char s1[]="zero";


    char separator[] = " ";

    char wejscie[1024];
    if (fgets(wejscie, 1024, stdin))
    {
        char* schowek = strtok(wejscie,separator); /* Removed '&'. */

        if(strcmp(wejscie,n)==0)
        {
            exit;
        }

        while (schowek)
        {
            printf("%s\n", schowek);
            schowek = strtok(NULL, separator);
        }
    }
    return 0;
}

Pozdrawiam

0

Proponowałbym umieszcze nie tego w strukturze zamiast dwóch osobnych tablic. Na szybko wymyśliłem coś takiego:

#include <stdio.h>
#include <string.h>

typedef struct {
    int value;
    char name[20];
} number_t;

/* end of numbers guard */
const number_t EMPTY = { -1, "" };

void init(number_t numbers[]);
void add_literal(number_t* number, const char* name, int value);
int find_value(const number_t numbers[], const char* name);
const char* find_name(const number_t numbers[], int value);
int is_end(const number_t* number);

int main() {
    char name[20];
    number_t numbers[50];
    
    init(numbers);
    
    /* example of usage */
    do {
        printf("Give number as string (type \"end\" to finish): ");
        scanf("%s", name);
        printf("Value of string \"%s\": %d\n", name, find_value(numbers, name));
    } while (strcmp(name, "end") != 0);
    
    return 0;
}

void add_literal(number_t* number, const char* name, int value) {
    number->value = value;
    strncpy(number->name, name, 20);
}

int find_value(const number_t numbers[], const char* name) {
    const number_t* num = numbers;
    while (!is_end(num)) {
        if (strcmp(num->name, name) == 0) {
            return num->value;
        }
        ++num;
    }
    return EMPTY.value;
}

const char* find_name(const number_t numbers[], int value) {
    const number_t* num = numbers;
    while (!is_end(num)) {
        if (num->value == value) {
            return num->name;
        }
        ++num;
    }
    return EMPTY.name;
}

int is_end(const number_t* number) {
    return number->value == EMPTY.value && strcmp(number->name, EMPTY.name) == 0;
}

void init(number_t numbers[]) {
    int i = 0;
    add_literal(&numbers[i++], "zero", 0);
    add_literal(&numbers[i++], "one", 1);
    add_literal(&numbers[i++], "two", 2);
    add_literal(&numbers[i++], "three", 3);
    add_literal(&numbers[i++], "four", 4);
    add_literal(&numbers[i++], "five", 5);
    add_literal(&numbers[i++], "six", 6);
    add_literal(&numbers[i++], "seven", 7);
    add_literal(&numbers[i++], "eight", 8);
    add_literal(&numbers[i++], "nine", 9);
    add_literal(&numbers[i++], "ten", 10);
    /* more numbers... */
    
    /* mark end of table */
    add_literal(&numbers[i++], EMPTY.name, EMPTY.value);
}

To w zasadzie tylko proof of concept i nie ma obsługi błędów, ale generalnie tak bym to widział. W metodzie init() można dodawać kolejne liczby wraz z literałami. Funkcja find_name() jest właściwie na wyrost, w razie gdybyś chciał tłumaczyć w drugą stronę (liczba -> nazwa). Najlepiej byłoby to wydzielić do osobnego modułu, a w nagłówku wystawić tylko find_value() i find_name().

0

Ok, trochę skomplikowane, ale jakoś się w tym odnajdę

Ja myślałem o czymś takim w mojej pętli while

    if(!strcmp(wejscie,"one") == 0)
            {
                n +=1;
            }
            if(!strcmp(wejscie, "two") == 0)
            {
                n +=2;
            }

Tylko nie wiem jak to poprawie rozpisać np. żeby nie dodawało liczb tylko je łączyło

0

Stwórz dwie tablice numbers i multipliers. Pierwsza zawiera liczby ("zero", "one", ... , "eleven", "twelve", ... , "twenty", "thirty", ... , "ninety") a druga mnożniki ("hundred", "thousand", "million", "billion").

Algorytm wygląda następująco (pseudokod):

int result = 0;
int tmp = 0;
foreach (word)
    if (word is number)
        tmp += valueof(word);
    else if (word is multiplier)
        tmp *= valueof(word);
        result += tmp;
        tmp = 0;
return result + tmp;

Oczywiście problem pojawia się, gdy chcesz walidować wprowadzoną słownie liczbę, bo przy tym (naiwnym) algorytmie "one two thousand seven million six six six" da w wyniku 7003018.

Edit Skopałem, niestety. Błędnie sparsuje liczbę two hundred one thousand one – da w wyniku 1201, a powinien 201001. :/ Poniżej poprawiony algorytm:

int result = 0;
int tmp = 0;
foreach (word)
    if (word is number)
        tmp += valueof(word);
    else if (word is multiplier)
        tmp *= valueof(word);
        if (valueof(word) > 100)
            result += tmp;
            tmp = 0;
return result + tmp;
0

mógłbyś to trochę bardziej rozpisać?
mogę użyć mojego odczytu do tego?

0

Jak najbardziej, ten cały foreach to nic innego jak twoje while (schowek).

0

Hm, zrobiłem to po swojemu, tak będzie dla mnie lepiej bo wiem co gdzie i jak.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main()
{
    int p=0,d=0,a,n1=0,a1;
    char separator[] = " ";
    char b[1024];
    char* schowek;

    while(gets(b))
    {
        a=a1=d=p=0;
        schowek = strtok(b,separator);
        while (schowek!=NULL)
        {
            n1=0;
            if(strcmp(schowek,"negative")==0)
                d=1;
            if(strcmp(schowek,"one")==0)
                p=1;
            else if(strcmp(schowek,"two")==0)
                p=2;
            else if(strcmp(schowek,"three")==0)
                p=3;
            else if(strcmp(schowek,"four")==0)
                p=4;
            else if(strcmp(schowek,"five")==0)
                p=5;
            else if(strcmp(schowek,"six")==0)
                p=6;
            else if(strcmp(schowek,"seven")==0)
                p=7;
            else if(strcmp(schowek,"eight")==0)
                p=8;
            else if(strcmp(schowek,"nine")==0)
                p=9;
            else if(strcmp(schowek,"ten")==0)
                p=10;
            else if(strcmp(schowek,"zero")==0)
                p=0;
            else if(strcmp(schowek,"eleven")==0)
                p=11;
            else if(strcmp(schowek,"twelve")==0)
                p=12;
            else if(strcmp(schowek,"thirteen")==0)
                p=13;
            else if(strcmp(schowek,"fourteen")==0)
                p=14;
            else if(strcmp(schowek,"fifteen")==0)
                p=15;
            else if(strcmp(schowek,"sixteen")==0)
                p=16;
            else if(strcmp(schowek,"seventeen")==0)
                p=17;
            else if(strcmp(schowek,"eightteen")==0)
                p=18;
            else if(strcmp(schowek,"nineteen")==0)
                p=19;
            else if(strcmp(schowek,"twenty")==0)
                p=20;
            else if(strcmp(schowek,"thirty")==0)
                p=30;
            else if(strcmp(schowek,"fourty")==0)
                p=40;
            else if(strcmp(schowek,"fifty")==0)
                p=50;
            else if(strcmp(schowek,"sixty")==0)
                p=60;
            else if(strcmp(schowek,"seventy")==0)
                p=70;
            else if(strcmp(schowek,"eighty")==0)
                p=80;
            else if(strcmp(schowek,"ninety")==0)
                p=90;
            if(strcmp(schowek,"hundred")==0)
            {
                a=a*100;
                n1=1;
            }
            if(strcmp(schowek,"thousand")==0)
            {
                a=a*1000;
                n1=1;
                a1+=a;
                a=0;
            }
            if(strcmp(schowek,"million")==0)
            {
                a=a*1000000;
                n1=1;
                a1+=a;
                a=0;
            }
            if(n1==0)
                a+=p;
            schowek = strtok(NULL, separator);
        }
        a1+=a;
        if(d==1)
            a1=-a1;
        printf("%d\n", a1);
    }
    return 0;
}

Niby wszystko dobrze działa wejscie i wyjście jest zgodne z tymi http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=427 ale przy wysyłaniu programu do sprawdzenia dostaje błędny wynik.

0

else if(strcmp(schowek,"eightteen")==0)

eighteen

nine hundred ninety nine milion nine hundred ninety nine thousand nine hundred ninety nine
101799999
0

Rzeczywiście, poprawiłem to. Ale nadal nic, szukam dalej, może bedzie jeszcze jakaś literówka. Ok. Znalazłem fourty = forty

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