1 / 43
Oct 2015

Witam. Rozwiązałem zadanie PP0504B na dwa sposoby, zwracające poprawnie wyniki dla dowolnych danych, łącznie z tymi podanymi w zadaniu, ale ciągle oznacza moje zadanie jako zwracające nieprawidłowy wynik. Co jest nie tak?

W C++;

#include <iostream>
#include <cstring>

using namespace std;

#define T_SIZE 1001

char* string_merge(char *, char *);

int main(){
    int t,n;
    char S1[T_SIZE], S2[T_SIZE], *S;

    cin >> t; /* wczytaj liczbę testów */
    cin.getline(S1,T_SIZE);

    while(t){
        cin.getline(S1,T_SIZE,' ');
        cin.getline(S2,T_SIZE);

        S=string_merge(S1,S2);
        cout << S << endl;
        //delete[] S;
        t--;
    }

    return 0;
}

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

    char merged[T_SIZE * 2 - 1];

    int j = 0;

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

        if(!s1[i] || !s2[i]) {
            break;
        }

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

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

    }
    merged[j] = '\0';

    return merged;

}

Zrobiłem to samo nawet w PHP i dalej rzekomo nieprawidłowe rozwiązanie;

<?php

$t = (int)fgets(STDIN);

for($i = 0; $i<$t; $i++) {

    $line = fgets(STDIN);
    $parts = explode(' ', $line);
    $n = min(strlen($parts[0]), strlen($parts[1]));
    $merged = "";

    for($j = 0; $j < $n; $j++) {
        $merged .= $parts[0][$j];
        $merged .= $parts[1][$j];
    }

    echo trim($merged).PHP_EOL;

}
  • created

    Oct '15
  • last reply

    Oct '21
  • 42

    replies

  • 4.1k

    views

  • 17

    users

  • 2

    likes

  • 15

    links

Jeżeli masz taką opinię o bezosobowym i bezstronnym komputerowym programie sędziującym, to jaką masz/będziesz miał o osobach usiłujących Ci pomóc?

Moje dwie rady:
!. Popraw tytuł swojego postu, na poprawny.
2. Dokładnie przeczytaj treść zadania.

AD 1.
Poprawny tytuł postu to:
Numer zadania. Nazwa [tytuł] zadania. Ewentualnie dodatkowo kod zadania w nawiasach kwadratowych [kod zadania]. Opis, pytania, swoje opinie, przypuszczenia i inne szczegóły umieszczaj w treści postu-pytania, a nie w temacie postu.

AD 2
Pomiliłem się, Jednak nie musisz tego robić.

Zastosowałem się zarówno do AD 1 jak i AD 2. Niestety nie pomogło to w rozwiązaniu zadania. Jakieś bardziej pomocne porady?

Piszę tylko o rozwiązaniu w c++.
Tablica [i każda inna zmienna] zadeklarowana lokalnie, widoczna jest tylko lokalnie, a więc tablica merged, mimo, że podajesz na zewnątrz jej adres jest na zewnątrz funkcji string_merge już niedostępna. Tablice tworzone dynamicznie, instrukcją new, istnieją do momentu ich skasowania - instrukcją delete []. I właśnie tak rozwiązać zadanie proponuje autor:

i umieści w nowej dynamicznie alokowanej tablicy znaków, do której zwróci wskaźnik

Można zadanie rozwiązać oczywiście po swojemu, ale czy testowałeś swoje na ideone.com?
http://ideone.com/jmvnO281 :
stdout:
Standard output is empty

Jeżeli chodzi o php, to nie wiem co jest źle, ale tu masz poradnik na temat wczytywania: http://pl.spoj.com/forum-old/viewtopic.php?f=10&t=1815&sid=953b96c5c2009656fa7df4b4d0f9e5cf21

PS
Ja, nie chce mi się liczyć, ale raczej dałbym: T_SIZE * 2 + 1
i zamiast:
if(!s1[i] || !s2[i])
napisałbym [dla mnie czytelniejsze]smile
if (s1[i] == '\0' || s2[i] == '\0')

Dzięki za odpowiedź.

Bardzo dziwne, że na ideone zwraca, że stdout jest empty, jesli u mnie na maszynie wyświetla poprawne wyniki? Z czego to może wynikać? Co więcej jak to ustosunkowac do Twojej odpowiedzi biorąc pod uwagę, że skoro u mnie wyświetla poprawnie odpowiedź, to i widoczność musi być prawidłowa w tym przypadku?

Moja wersja gcc:

gcc version 4.9.2 (Ubuntu 4.9.2-10ubuntu13)

Właśnie się zastanawiałem, czy może testowałeś u siebie. ALe w takim razie w jakim kompilatorze zgłaszałeś na spoj.pl? Bo to co napisałem wyżej, to może zależeć np od kompilatora - zachowanie nieudokumentowane kompilatora, i używając innego [tu C++ 4.3.2] jest faktycznie [może przypadkowo?] dobrze:
http://ideone.com/yxDten25
Błędnie [pusty output] to C++ 5.1

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: