Szyfr Cezara - SPOJ

0

Cześć, robię zadanie ze SPOJa, jednak pokazuje mi nieprawidłowy wynik.
Mój kod:

import java.util.*;
class Cesar {
    public static void main(String[] args) {
    	Scanner input = new Scanner(System.in);
cezar(input.nextLine());
    }
  public static String cezar(String str) 
    {
    char z[] = str.toCharArray(); 

    for(int i=0; i!=z.length ; i++) 
    {
    int n = z[i]; 
    n+=3; 
    z[i]=(char)n;
    } 
    String str2 = new String(z);
    System.out.print(str2.replace("#", " "));
    return new String(z);
    }
}

Gdy kompiluję na komputerze wszystko jest w porządku. Jakieś pomysły?

1

a "z" na co się zamienia?

0

Załatwiłem to w ten sposób

 System.out.print(str2.replace("}", "C").replace("#", " ").replace("{", "B").replace("|", "A"));

Jednak nadal ten sam błąd, wypisałem cały alfabet i wynik w Eclipse prawidłowy.

0

jeszcze są małe litery

0

Na wejściu podajemy łańcuch dużych liter bez polskich znaków.

Nie wspomniałem o tym, ale na SPOJu jest tak napisane. Chyba, że jest błąd w poleceniu.

0

odświeżam temat z własnym kodem ->

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

char cezar(char znak);
int main()
{ 

    string tekst;
    int dlugosc,i;
    
    getline(cin,tekst);
    dlugosc=tekst.length();
    
    for(i=0;i<dlugosc;i++)
    cout<<cezar(tekst[i]);
    
  
 getch();
 return 0;
}

char cezar(char znak)
{
    char nowy_znak;
   
    
                          
                             nowy_znak=znak+3;
                             if (nowy_znak==91) nowy_znak=65;
                            if (nowy_znak==92) nowy_znak=66;
                            if (nowy_znak==93) nowy_znak=67;
                            if (nowy_znak==35) nowy_znak=32;
                             return nowy_znak;
                           
                             
                                   
    
}

 

Tez nie wiem dlaczego SPOJ go nie przyjmuje (błędna odpowiedź)

0

No pewnie z powodu tego getch()...

0

te ify mnie przerażają... użyłbyś else if albo switch. a najlepiej by było, jak byś sprawdził czy znak jest z jakiegoś przedziału (np. 91 do 93) i odjął od tego 26 (91-65, 92-66, 93-67)

0

getch(); razem z biblioteką conio.h usuwam przy zgłaszaniu kodu, a estetyka chyba raczej duzo nie zmienia pod kątem "błednych wyników"

0
dawidgarus napisał(a):

te ify mnie przerażają... użyłbyś else if albo switch. a najlepiej by było, jak byś sprawdził czy znak jest z jakiegoś przedziału (np. 91 do 93) i odjął od tego 26 (91-65, 92-66, 93-67)

Zmieniłem na

if (nowy_znak>=91 && nowy_znak<=93) nowy_znak=nowy_znak-26;

ale dalej to samo

0

starczy if ((nowy_znak>90)) nowy_znak=nowy_znak-26;
Poza tym ja mam dodatkowo sprawdzenie if (znak>='A'&&znak<='Z'), zaś wczytuję po znaku do końca strumienia wejściowego, nie wiem czemu zakładasz że będzie tylko jedna linijka.

ps niepotrzebnie skomplikowałeś ten kod ja mam dużo prostszy i zaakceptowany.

0

@Broch: warto używać stałych - przydają się...

Kod w C++:

#include <iostream>
#include <string>

using namespace std;

const int ALPHABET_SIZE = 'Z' - 'A' + 1;
const int CEZAR_SHIFT = 3;
 
// dziala tylko dla DUZYCH liter
char cezar_encode(char znak)
{
    return 'A' + ((znak - 'A' + CEZAR_SHIFT) % ALPHABET_SIZE);
}

char cezar_decode(char znak)
{
    return 'A' + ((ALPHABET_SIZE + znak - 'A' - CEZAR_SHIFT) % ALPHABET_SIZE);
}

int main()
{ 
 
    string tekst;
    int dlugosc,i;
 
    tekst = "ATOJESTTESTZ";

    dlugosc=tekst.length();
 
    for(i=0;i<dlugosc;i++)
    {
      tekst[i] = cezar_encode(tekst[i]);
    }

    cout << "Zakodowane: " << tekst << endl;

    for(i=0;i<dlugosc;i++)
    {
      tekst[i] = cezar_decode(tekst[i]);
    }
 
    cout << "Odkodowane: " << tekst << endl;
 
    return 0;
}

Test:
http://ideone.com/E4ZEE

0

Nie bardzo rozumiem jak to robisz? Wczytujesz tekst jako tablice char'ów ? Skąd wiesz ile będzie miała ona pól?

0
vpiotr napisał(a):

@Broch: warto używać stałych - przydają się...

Kod w C++:

#include <iostream>
#include <string>

using namespace std;

const int ALPHABET_SIZE = 'Z' - 'A' + 1;
const int CEZAR_SHIFT = 3;
 
// dziala tylko dla DUZYCH liter
char cezar_encode(char znak)
{
    return 'A' + ((znak - 'A' + CEZAR_SHIFT) % ALPHABET_SIZE);
}

char cezar_decode(char znak)
{
    return 'A' + ((ALPHABET_SIZE + znak - 'A' - CEZAR_SHIFT) % ALPHABET_SIZE);
}

int main()
{ 
 
    string tekst;
    int dlugosc,i;
 
    tekst = "ATOJESTTESTZ";

    dlugosc=tekst.length();
 
    for(i=0;i<dlugosc;i++)
    {
      tekst[i] = cezar_encode(tekst[i]);
    }

    cout << "Zakodowane: " << tekst << endl;

    for(i=0;i<dlugosc;i++)
    {
      tekst[i] = cezar_decode(tekst[i]);
    }
 
    cout << "Odkodowane: " << tekst << endl;
 
    return 0;
}

Test:
http://ideone.com/E4ZEE

Dzieki ale to raczej nie rozwiązuje mojego problemu, moj program też potrafi zakodować tekst, jak zauwazył Sig problem tkwi raczej w jego wczytywaniu funkcją getline();

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

using namespace std;

   char tekst[9999];
   int i=0;
   int cezar;
   char znak;

int main()
{
    cin.getline (tekst,9999);
    while (tekst[i] != '\0') {
      cezar = tekst [i];
      cezar = cezar + 3;
      if (cezar == 35) cezar = 32;
      if (cezar > 90) cezar = cezar - 26;
      znak = cezar;
      cout << znak;
      i++; }
      getch();
    return(0);
}

tez mi nie przeszlo

0
#include <iostream>
#include <conio.h>
 
using namespace std;
 
   
 
int main()
{
    
    char tekst;
    
    
    while (cin >> tekst) 
    {
    if(tekst >='A' && tekst <= 'Z')
      {
       tekst = tekst  + 3;
       if (tekst > 90) tekst = tekst - 26;
      }
      
    if(tekst == 32)cout<<" ";
    else cout << tekst;
     
    }
      
    return(0);
}

Dzieki @sig uprościłem kod do kilku linijek jednak to rozwiązanie niestety nie obsługuje spacji (próbowałem ją wstawić na chama ale to na nic) , nie ma również warunku do zakończenia programu

0

warunek jest, to while (cin >> tekst) w momencie końca strumienia wczytywania ta pętla przestanie się wykonywać. Dalej ci nie działa? dziwne masz tu mój zatwierdzony kod, pewnie jakiś drobny błąd, albo te dodatkowe spacje

#include <iostream>

using namespace std;

int main()

{
    char znak;
     while(!(cin.get(znak)).eof())
     {
        if (znak>='A'&&znak<='Z')
        {
            znak=znak+3;
            if ((znak>90)) znak=znak-26;
        }
        cout << znak;

    }

}

generalnie o wczytywaniu i wypisywaniu na spoju w c++ masz [url=http://pl.spoj.pl/forum/viewtopic.php?f=10&t=1207= tutaj [/url].

edit: właśnie widzę że mam while-a dziwnego jakiegoś, być może to jest przyczyna. Ale to dość stary kod, być może tego co wcześniej pisałem jeszcze nie stosowałem.

0

Tak to wina tej pętli teraz już jest dobrze, ale mam pytanie u mnie w kompilatorze ta pętla jest nieskończona, program sie nie wyłącza, czy można zrobić żeby było inaczej ?

0

Nie wiem jak tam ty, ale ja spoj-owe programy testuję zwykle podając im "wejście" z pliku. "Sędzia" też tak robi. Ale jak to zrobić pod Windowsem sam musisz poszukać.

ps nic dziwnego że się nie wyłącza, albo mi się wydaje albo czeka aż znak będzie równy końcowi pliku a to przy wpisywaniu z klawiatury raczej się nie zdarza. Generalnie tą pętlę ma tylko dlatego że to jeden z moich pierwszych spoj-owych programów, nie wiem czy nie pierwszy z nieokreśloną liczbą danych wejściowych.

1

Przekierowania stdin i stdout http://oi.edu.pl/l/oi_stdin/

Ale ogólnie do takich zadań to w przypadku spoja wystarczy wybrać odpowiednie narzędzie, np. rozwiązanie w Ruby:

puts $_.tr('A-Z', 'D-ZA-C') while gets

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