12 / 43
Sep 2016

Spróbowałem wszystkich wersji C++ dostępnych przy zgłaszaniu rozwiązania i dalej nic confused

Napisałem na szybko fixa dla potomnych, ale dalej uważam, że to zachowanie jest bardzo dziwne i nie wiem czym może być spowodowane:

char* string_merge(char* s1, char* s2) {

    char* merged = (char *)malloc((T_SIZE * 2 - 1) * sizeof(char));

    int j = 0;

    for(int i = 0; i < T_SIZE; i++) {

        if(s1[i] == '\0' || s2[i] == '\0') {
            break;
        }

        merged[j] = s1[i];
        j++;

        merged[j] = s2[i];
        j++;

    }
    merged[j] = '\0';

    return merged;

}

(to zostało zaakcpetowane)

Widzę, że już AC wink, Najprościej byłoby zrobić twoją tablicę tablicą globalną i dostaniesz AC, ale zmienne globalne to zło [zła praktyka programowania], więc lepiej dynamicznie.

Przecież Ci napisałem wcześniej, więc czemu tak piszesz i co tu jest dla Ciebie ciągle bardzo dziwne i nie zrozumiałe?
Może napiszę inaczej. Nie można tak pisać, bo czasami zadziała, a czasami nie. Po wyjściu z funkcji, zmienne lokalne zostają potraktowane jako wolna pamięć i w zależności jak i gdzie kompilator wszystko powstawiał, grozi nadpisanie pamięci innymi danymi, np zerami - a wtedy twój program nic nie wypisuje.

Więc powiem Ci tak, daruj sobie pisanie dla potomnych - wątpię czy ktokolwiek nawet wspólcześnie zajrzy do tego. Czy Ty, [nie potomny] przeczytałeś to co ja napisałem? Dlaczego więc inaczej mieliby postąpić potomni? Raczej będą ciągle na nowo tworzyli [pisali] listy ze starymi jak świat pytaniami ze znanymi, prawie wszystkim, odpowiedziami.

PS
I dla potomnych lepiej byłoby zostawić wędkę, a nie gotową rybkę, Dlatego raczej nie zostawiamy tu gotowych rozwiązań, czy działających kodów. Więc powinieneś pousuwać wszystkie swoje kody, bo twój błędny kod + moje wyjaśnienia + twój napisany na szybko fix dla potomnych == rybka, czyż nie?

10 months later

Hej,
Co źle zrobiłem?
http://ideone.com/oX3xaS61
Funkcja wygląda ok...może źle rozumiem treść zadania ?
Z góry dzięki za pomoc :wink:
Edit bład jaki wyświetla sędzia => SIGABRT
Dobra już wiem gdzie miałem błąd - pytanie nadal mam - dlaczego dynamiczna tablica dynamicznie sie nie rozszerza kiedy zachodzi taka potrzeba ? Tylko muszę dynamicznej tablicy zadeklarować poprawnie ilość komórek ??

to oczywiście pisanie poza zakresem tablicy, nie masz ich dużo w programie, to szybko znajdziesz :slight_smile:

przecież ona nie jest dynamiczna :), ona ma taką wielkość, jaką zadeklarowałeś

Ok, dzięki :wink: Jak więc deklaruje się tablice dynamiczną w tym konkretnym przypadku ? Może coś się nauczę :wink:

Coś się douczyłem i chyba już rozumiem....Tutaj tablica jest dynamiczna z nazwy ale chodzi o dynamiczne alokowanie pamięci.
Jeśli chcielibyśmy użyć "tablicy" którą możemy dynamicznie powiększać musimy użyć kontenera np vector?

I jeszcze jedno pytanie - co nam te char* string_merge(char* s1, char* s2) wskaźniki dają ? Przecież nie korzystamy tutaj z referencji. ani nie pracujemy na wskaźnikach już w środku funkcji?

2 months later

Witam mam problem z zadaniem. Jak wpisuje a bb lub afr der to na końcu mam śmieci. Ale jak wpisze wqeqweqweq eqweqwe to już wszystko gra. Domyślam się że gdzieś mam błąd z rozmiarami tablic ale nie wiem gdzie i zastanawiam się czy nie dodać jakiegoś if który za zadanie miałby by sprawdzić jak duża jest tablica i wtedy manipulowałby rozmiarem tablicy.
http://ideone.com/viEpa437

Linijka 34:
popraw na:

char* text_final2 = new char[size_tab_final + 1];

Dodaj przed returnem:

text_final2[size_tab_final] = '\0';

Po tym będzie AC.

Tylko tak się zastanawiam po co męczyć się ze wskaźnikami skoro możesz użyć obiektu string? Na przyszłość zajrzyj do biblioteki standardowej. Znajdziesz tam wiele przydatnych gotowych klas i algorytmów.

3 months later

Cześć! Czy ja też mogę zadać pytanie do tego zadania? To moje pierwsze dni na SPOJu i gdzieś przeczytałam, że sędzia sprawdza input i output zadania. Czy zatem mogę się nie do końca zastosować do treści? W poniższym nie ma char* i nie ma wskaźnika do tablicy alokowanej dynamicznie, czy zatem jest to powód do "błędnej odpowiedzi"?

include

include

using namespace std;

int t;
string StringMerge(string S1,string S2)
{
int n=min(S1.length(),S2.length());
string napis;
int j=0;
while(n>0)
{
napis=napis+S1.substr(j,1)+S2.substr(j,1);
n--;
j++;
}
napis+='\0';
return napis;
}

int main()
{
cin >> t;
string S1,S2;
do
{
cin>> S1>>S2;
cout << StringMerge(S1,S2);
t--;
}while (t>0);
return 0;
}

kod jest jaki jest, dopiero zaczynam, proszę o wyrozumiałość

Tak, sędzia nie sprawdza czy masz funkcję dokładnie taką jak w treści zadania. Interesuje go tylko czy odpowiedź jest poprawna. Więc nie to jest powodem błędnej odpowiedzi.

Sprawdź sobie różnice pomiędzy stringami, a C-stringami w języku C++. Robisz ze stringiem coś, co nie jest wymagane przy pracy z nim, a z kolei sędzia tego nie toleruje.
Następna rzecz, to Twoje wyjście jest nie do końca takie samo, jak wymagane.

Jeśli to poprawisz, to pojawi się AC na zielonym tle, co Cię z pewnością ucieszy :slight_smile:

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!