Професионална програма
Loading...
+ Нов въпрос
m.nikolov97 avatar m.nikolov97 21 Точки

01. TryParse [check if string is integer]

Здравейте, колеги!

Първа задача, първи въпрос - така започва курсът за мен laugh

Въпросът ми е защо първоначалното ми решение ми даде 20/100 и каква е разликата с второто решение, което сработи.

Първоначално създадох функцията TryParse.h, където приемам стринг-а от входа и integer (естествено по референция, за да мога да променя стойността му) . До тук добре, но исках да намеря най-добрия начин за проверка - дали стрингът съдържа само и единствено int. 

Първоначално създадох (намерих в интернет) следната функция за проверката:

bool isNumber(const string& s) 
{
	return !s.empty() && all_of(s.begin(), s.end(),::isdigit);
}

За жалост, въпреки че на моя компютър програмата работеше, Judge ми даде само 20/100 (само 2-та Zero Tests и Test #1 ми бяха correct).

След известно лутане, реших, че проблемът в решението ми е именно в тази функция и намерих друга функция, която използвах и решнието ми сработи:

inline bool isInteger(const std::string & s)
{
   if(s.empty() || ((!isdigit(s[0])) && (s[0] != '-') && (s[0] != '+'))) return false;

   char * p;
   strtol(s.c_str(), &p, 10);

   return (*p == 0);
}

За пръв път използвам strtol, много ми хареса като функция и все още я разучвам, но не мога да разбера какъв е проблемът с първият вариант на функцията ми - какво изпускам там за разлика от втората?

Благодаря предварително на всеки, който отдели от времето си, за да ми разясни казуса! smiley

0
C++ Advanced
NinessonC avatar NinessonC 4 Точки

Здравей, аз имах същия проблем като теб, но след като сложих проверка дали числото е отрицателно, джъдж ми даде 100/100. Цялата проверка я сведох до:

if (isdigit(str[i]) || str[i] == '-')

 

1
dmartinov avatar dmartinov 36 Точки

И при двама ви, не е сработило защото на входа има стринг, а при отрицателно число записано в string минусът се репрезентира като char-a тире, а не като знаковата стойност минус. Съответно после е минало когато сте добавили тази проверка. Когато имаш стринга "-56" на входа, isdigit(str[i]) ще върне false при първата итерация и така никога няма да запишеш в променливата си отрицателно число.

Аз реших проблема като създадох входен поток - ако успея да запиша стринга в int, връщам true, ако не успея - false. По този начин директно взимам целия стринг и гледам дали от него може да се извлече int, a не го проверявам char по char. Това работи, защото условието на задачата е такова, че не се налага да "изчистим" стринга и да извлечем само цифрите от него. Тоест, няма да имаш 5j67kd6 на входа и да се налага да извлечеш 5676 с, което после да правиш някакви аритметични операции (подобно на задачите signal and the noise и noise and the signal).

Ето го и моят вариант:

bool tryParse (const std::string& inputString, int& outputNumber) {

    std::istringstream iss(inputString);

    if (iss >> outputNumber) {
        outputNumber = std::stoi(inputString);
        return true;
    } else {
        return false;
    }
}

 

2
27/11/2019 16:26:33
MartinBG avatar MartinBG 2792 Точки

Няма нужда от outputNumber = std::stoi(inputString);,  тъй като при успешен iss >> outputNumber числото вече е прочетено:

bool tryParse (const std::string& inputString, int& outputNumber) {

    std::istringstream iss(inputString);

    if (iss >> outputNumber) {
        return true;
    } else {
        return false;
    }
}

 

0
zzerro avatar zzerro 14 Точки

В скелетона има грешка при четенето, която обаче в джудж е оправена:

...
	std::string aString, bString;
	std::cin >> aString >> bString;
...

Това няма да прочете целия израз заедно с интервалите, а ще спре до първия интервал.

Аз проверих с getline(std::cin, aString) дали ще ми работи, а в джудж ми даде 100/100.

0