20 / 43
Mar 2017

Jeśli chodzi o różnicę między C-string a string to domyśliłam się, że niepotrzebnie robie +'\0'.
'Twoje wyjście jest nie do końca takie samo, jak wymagane'
a tutaj czy masz na myśli to że nie mam najpierw bloku in a dopiero potem bloku out? Tu też gdzieś przeczytałam, że nie musi tak być, że sędzia sam rozpoznaje co jest in a co out. Ale może robię błąd w sklejaniu?

Tak, stringi nie kończą się terminatorem i jeśli go tam dodasz, to przy wypisywaniu ten znak również zostanie wypisany, inaczej niż przy wypisywaniu C-stringa.

Za dużo kombinujesz. W treści zadania czytamy: "Output: W każdej linii jeden łańcuch". W domyśle: jedna linia wyjścia na jeden test. U Ciebie wszystko jest wypisywane w tej samej linii. Dodaj endl po wypisaniu stringa i sędzia będzie zadowolony.

7 months later

Witam. Dopiero zacząłem się uczyć C++, więc wielu rzeczy jeszcze nie rozumiem. W moim kompilatorze program działa bez problemu, ale SPOJ go nie akceptuje. Pojawia mi się błąd wykonania (SIGSEGV). Nie bardzo wiem, o co chodzi. W którym miejscu zrobiłem błąd? Poniżej mój kod:

#include <iostream>

using namespace std;

void f(string a1, string b1);

int main()
{
    int ile;
    cin>>ile;
    for(int i=0;i<ile;i++)
    {
        string a,b;
        cin>>a>>b;
        f(a,b);

    }
    return 0;
}

void f(string a1,string b1)
{
    int dl_a=a1.length();
    int dl_b=b1.length();
    if(dl_a<dl_b)
    {
        int ii=0;
        char wynik[dl_a*2];
        for(int i=0;i<dl_a;i++)
        {
            wynik[ii]=a1[i];
            wynik[ii+1]=b1[i];
            ii=ii+2;
        }
        wynik[dl_a*2]='\0';
        cout<<wynik<<endl;
    }
    else
    {
        int ii=0;
        char wynik[dl_b*2];
        for(int i=0;i<dl_b;i++)
        {
            wynik[ii]=a1[i];
            wynik[ii+1]=b1[i];
            ii=ii+2;
        }
        wynik[dl_b*2]='\0';
        cout<<wynik<<endl;
    }
}

Będę wdzięczny za każdą pomoc :slight_smile:

w twoim przypadku, SIGSEGV oznacza błąd przy próbie zapisu do nieistniejącego elementu tablicy - sam poszukaj, gdzie to robisz

i po co ci dwa prawie takie same fragmenty kodu w funkcji f() ? - przecież wystarczy dać na początku:

if (dl_a >dl_b)
      dl_a = dl_b;

a kod będzie krótszy i będzie wyglądał dużo ładniej

Wielkie dzięki za szybką pomoc :slight_smile:

Poprawiłem linię:

char wynik[dl_b*2];

na:

char wynik[dl_b*2+1];

i dostałem akceptację :slight_smile:
Pozdrawiam!

9 months later

Czy mógłby ktoś rzucić okiem. Wyrzuca mi błąd kompilacji.

i nie wiem dlaczego.

gdzie bład kompilacji? Na ideonie działa, a jeśli na spoju to klikasz na info i otwiera sie strona z dokładniejszymi informacjami. Czasem trzeba np. dodać dodatkowego includa…

Czego? Napis błąd kompilacji jest linkiem, który zawiera dodatkowe informacje. Tu akurat w 27 linijce jest zbędne {}. Ale po za tym nie działa jak należy

Witam ,
Bardzo proszę o pomoc, nie wiem czemu sędzia wyrzuca błąd odpowiedzi.
Test na podsatwie przykładu z zadania wychodzi poprawnie.

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

using namespace std;

char* stringMerge(char* str1,char *str2)
{
int dlstr1 = 0, dlstr2 = 0, dlnowy = 0;

dlstr1 = strlen(str1);
dlstr2 = strlen(str2);

if (dlstr1 <= dlstr2)
dlnowy = dlstr1;
else dlnowy = dlstr2;

char *nowyString ;

dlnowy = 2*dlnowy;
nowyString = new char [dlnowy+1];

//cout << "dlugosc: "<<dlnowy<< endl;

int i=0,j=0;

do
{
    nowyString[i] = str1[j];
    i++;
    j++;
    nowyString[i] = str2[j-1];
    i++;
}while(i<dlnowy);

//nowyString[dlnowy] = '/0';

// cout << "ostatni "<<nowyString[dlnowy] << endl;

return nowyString;

}

string napis1, napis2;

int main()
{
char *nowySTR;
int ilosc_testow;
string *tabwynikow;

// cout << "podaj ilosc testow : "<< endl;
cin>>ilosc_testow;

tabwynikow = new string[ilosc_testow];

for(int i=0; i<ilosc_testow;i++)
{
   //cout << "podaj stringi "<< endl;
   cin>>napis1>>napis2;
   nowySTR = stringMerge(&napis1[0], &napis2[0]);

   tabwynikow[i] = nowySTR;
  // delete [] nowySTR;
}

for(int i=0;i<ilosc_testow;i++)
{
    cout<<tabwynikow[i]<<endl;
}


delete [] tabwynikow;
return 0;

}

Najlepiej wstawiać kod jako link do ideone… Od razu można sprawdzić. Teraz jestem na tel i z tym nie zrobię nic. Co mi sie nie podoba to że napisy pobierasz jako stringi i pozniej coś kombinujesz by przekazać do funkcji.

Powyżej link.
Spróbuję napisy podać do funkcji jako wskaźnik do tablicy.

Dzięki yula :grinning: to był właśnie ten problem z przekazaniem do funkcji stringów. Pozdrawiam! :smiley:

2 months later

Hej, Czy mógłby ktoś pomóc zweryfikować? Wydaje się, że działa poprawnie aczkolwiek, nie zalicza mi tego zadania? Z Góry dzięki za pomoc.

Wykłada się nawet dla przykładowych danych

Tak dzięki, tutaj popełniłem błąd logiczny. “Należy wziąć po tyle znaków ile jest w krótszym łańcuchu” zrobiłem jako “Należy wziąć tyle znaków ile jest w krótszym łańcuchu”.
Błąd poprawiłem już przynajmniej dla testowych i podobnych przypadków daje poprawne wyniki. Jednak nadal nie zalicza odpowiedzi.

1 month later

Jaki masz problem? Co chcesz zrobić? Co dokładnie nie działa? Kryształowa kula mi się ostatnio zepsuła :wink:, więc nie wiem, o co chodzi.

Przechodząc do pierwszego kodu:

  1. gets() jest funkcją, której nie powinno się używać (poszukaj w internecie czemu). Dodatkowo wczytuje ona całą linię, co nie zadziała, gdyż napisy są podane w jednej linii. Zamiast niej najlepiej użyć scanf ("%s", tekst);.
  2. W funkcji string_merge zwracasz wskaźnik na dynamicznie utworzoną tablicę. Wszystko byłoby ok, tylko najpierw używasz tego wskaźnika do wypisania, a potem drugi raz wywołujesz swoją funkcję, używając free, przez co pamięć zarezerwowana podczas pierwszego wywołania jest tracona. Poprawnie powinieneś zrobić np. tak:
char* nowy = string_merge(tekst,tekst1);
printf("%s", nowy);
free(nowy);
  1. Rezerwujesz tablicę na 1000 znaków. Czy aby tyle na pewno wystarczy? C-stringi muszą się przecież czymś kończyć :wink: .

Drugi kod:

  1. Zamiast używania wskaźnika w ten sposób: *(wskaznik + 1) możesz po prostu użyć wskaznik[1], o wiele przyjemniej wygląda :slight_smile: .
  2. Odnośnie tego fragmentu: gets(tekst); if(tekst!=NULL): nazwa tablicy używana jako wskaźnik zawsze na coś wskazuje, więc if wykona się zawsze. Żeby otrzymać efekt, którego prawdopodobnie oczekiwałeś, przypisz nowemu wskaźnikowi wartość zwracaną funkcji. Potem możesz ten nowy wskaźnik przetestować, czy na coś wskazuje.

Powodzenia :slight_smile: