Szyfr Cezara

0

Cześć, muszę zrobić zadanie na SPOJ https://pl.spoj.com/problems/JSZYCER/
Wydaję mi się, że sam kod jest w porządku, ale wyskakuje błąd podczas testu.
Myślę, że chodzi o linijkę if (zdanie[i] == ' ' || zdanie[i] == '\n') continue;

Cały kod:

string wpisz, wypisz;
            char[] alfabet = new char[] { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};

            wpisz = Convert.ToString(Console.ReadLine());
            char[] zdanie = wpisz.ToCharArray();

            char[] zaszyfrowane = new char[zdanie.Length];

            for (int i = 0; i < zdanie.Length; i++)
            {
                char litera = zdanie[i];
                if (zdanie[i] == ' ' || zdanie[i] == '\n') continue;
                int pozycja = Array.IndexOf(alfabet, litera);
                int nowaPozycja = (pozycja + 3) % 26;
                char literaZaszyfrowana = alfabet[nowaPozycja];
                zaszyfrowane[i] = literaZaszyfrowana;
            }

            wypisz = string.Join("", zaszyfrowane);
            Console.WriteLine(wypisz);

0

A jaki error? Może index out of range execption? W for przekraczasz index.

1

Zakładając, że np. zdanie[5] = ' ';, co - po zakończeniu całej Twojej pętli - będzie się znajdowało pod zaszyfrowane[5]?

0

Jakbyś to sobie jakoś zaimplementował w funkcji, (circular array) to by łatwiej było testować. A tak to jest mess.

0

Nie znam Dawno temu używałem C#, ale czy Console.ReadLine nie czyta tylko jednej linii? A w poleceniu nie ma wzmianki, że linii będzie 1.

0

@Patryk27: czy to ma być coś w tym stylu?

                if (zdanie[i] == ' ')
                {
                    Console.WriteLine(' ');
                }
0
if (zdanie[i] == ' ')
{
    zaszyfrowane[i] = ' ';
}
0

@Patryk27: Hmm, mam coś takiego:

string wpisz, wypisz;
            char[] alfabet = new char[] { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};

            wpisz = Convert.ToString(Console.ReadLine());
            char[] zdanie = wpisz.ToCharArray();

            char[] zaszyfrowane = new char[zdanie.Length];

            for (int i = 0; i < zdanie.Length; i++)
            {
                if (zdanie[i] == ' ') zaszyfrowane[i] = ' ';
                else if(zdanie[i] == '\\') continue;
                else if(zdanie[i] == 'n' ) zaszyfrowane[i] = '\n';
                else
                {
                    char litera = zdanie[i];
                    int pozycja = Array.IndexOf(alfabet, litera);
                    int nowaPozycja = (pozycja + 3) % 26;
                    char literaZaszyfrowana = alfabet[nowaPozycja];

                    zaszyfrowane[i] = literaZaszyfrowana;
                }
                
            }

            wypisz = string.Join("", zaszyfrowane);
            Console.WriteLine(wypisz);

Wpisałem tekst ze spacją oraz nową linią i niby działa, aczkolwiek na spoj jest błędna odpowiedź. Czy są inne możliwości na nową linię, czy po prostu coś schrzaniłem?

1
if(zdanie[i] == '\\') 

^ w jakim celu istnieje ten warunek?

if(zdanie[i] == 'n' )

^ na pewno n?

Btw:

https://docs.microsoft.com/en-us/dotnet/api/system.io.streamreader.readline?redirectedfrom=MSDN&view=net-5.0#System_IO_StreamReader_ReadLine:
[...] The string that is returned does not contain the terminating carriage return or line feed.

(innymi słowy: \n nigdy nie wystąpi w zdanie, więc nie ma sensu sprawdzać tego.)

0

@Patryk27:

string wpisz, wypisz;
           char[] alfabet = new char[] { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};

           wpisz = Convert.ToString(Console.ReadLine());
           char[] zdanie = wpisz.ToCharArray();

           char[] zaszyfrowane = new char[zdanie.Length];

           for (int i = 0; i < zdanie.Length; i++)
           {
               if (zdanie[i] == ' ') zaszyfrowane[i] = ' ';
               else
               { 
                   char litera = zdanie[i];
                   int pozycja = Array.IndexOf(alfabet, litera);
                   int nowaPozycja = (pozycja + 3) % 26;
                   char literaZaszyfrowana = alfabet[nowaPozycja];

                   zaszyfrowane[i] = literaZaszyfrowana;
               }
               
           }

           wypisz = string.Join("", zaszyfrowane);
           Console.WriteLine(wypisz);
0

Na moje oko wygląda prawidłowo - SPOJ nadal zwraca Ci błąd?

1
            string wpisz="" ,line= "";
            while (!String.IsNullOrWhiteSpace(line = Console.ReadLine()))
            {
                wpisz += line + Environment.NewLine;
            }
           
               
            StringBuilder stringBuilder = new StringBuilder();
            foreach (char a in wpisz)
            {
                if (a >= 'A' && a <= 'Z') 
                {
                    char b =(char)(a + 3);
                    if (b > 'Z')
                    {
                        b =(char)(b-('Z'-'A'+1));
                    }
                    
                    stringBuilder.Append(b);
                }
                else
                {
                    stringBuilder.Append(a);
                }

            }

            stringBuilder.Length -= 1;
            Console.WriteLine(stringBuilder.ToString());

Trochę poprawiłem twój kod tak by nie trzeba było samemu ręcznie wpisywać liter do tablicy. Nazwy zmień na angielskie i mające sens bo ja wykorzystałem twoje a swoje jedną literką pisałem (tak się nie powinno robić ,ale zostawiłem ci troszkę do zrobienia). A co do samego błędu to problem był taki ,że trzeba wczytywać do pustej linii a nie tylko jedną linie. No i oczywiście program się sypnie jak podasz mu pustego stringa. Ale do sprawdzarki tak jest jedna instrukcja mniej.

screenshot-20201124151626.png

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