1

I have problem solving this problem. The task is simple at first line I enter how many examples I have. On second line I need to enter how many numbers im going to read. and then we enter all the numbers separate by space. The task itselfs do , sorting the string array wtih numbers from smalles to the biggest one. After that if we have even numbers entered we print the middle number -1, if they are uneven we just print the middle number.

So far if I use the exact same code with long long it works perfectly , but it is limited only to 19 digit number and I want to expand the program so it can use bigger numbers.

Using that way the sort func , when I try to sort 16 elements from 160 to 10 , they all messed it start from 110 then in the midle is 160 and so one , which makes absolutly non sense, using 5 numbers or 8 works perfectly w/o any problem , using more numbers fails.

#include <iostream>
#include <algorithm>
#include <string>

using namespace std;




int main() {
int examples;
cin >> examples;
for (size_t i = 0; i < examples; i++)
{
    long long unsigned int  n;
    cin >> n;
    string * numbers = new string[n];
    for (size_t i = 0; i < n; i++)
    {
        cin >> numbers[i];
    }

    sort(numbers, numbers + n);

    if (n % 2 == 0) {
        cout << numbers[n / 2 - 1];
    }
    else
        cout << numbers[n / 2];



}

system("pause");
return 0;
}
JohnSmithEr
  • 23
  • 1
  • 6
  • 1
    Did you try using the debugger? – Algirdas Preidžius Nov 23 '16 at 12:56
  • 1
    There are a few "bignum" libraries. Try and search a little. – Some programmer dude Nov 23 '16 at 12:56
  • take a look at `__int128` – Raindrop7 Nov 23 '16 at 12:57
  • You also have a memory leak in your program. I suggest you use `std::vector` instead. – Some programmer dude Nov 23 '16 at 12:58
  • Lastly, if you insist on using strings, try making all strings the same size and pad the short strings with *leading* zeroes. – Some programmer dude Nov 23 '16 at 13:00
  • its not about using big num librarier , I want to make it with string , and apperently the whole problem is in the sort func itself, when I try to sort from 160 to 10 it prints 10, 110,120,130,140,150,160,20,30 ... so it cleary thinks that 110 is smaller then 20 which is WTF , so it definetly not sum all the ASCI code numbers from all numbers if the sort use to sum 110 asci code aka - 49+49+48 it will be bigger then 20 which is 50+48 so I suppose I need to write my own algorithym to sort string :S.. – JohnSmithEr Nov 23 '16 at 13:07
  • It's not a WTF. It's how *strings* works when sorted. The string `"10"` *is* "smaller" than the string `"2"`. Take a look at [an ASCII table](http://en.cppreference.com/w/cpp/language/ascii) to understand why (`'1' < '2'`) – Some programmer dude Nov 23 '16 at 13:10
  • 1
    You should add padding yourself. Also, you can use std::nth_element to get your answer (n-th element), as it's quicker than sort. – Alexander Anikin Nov 23 '16 at 13:14
  • Yes because sort func sorting 1 < 2 and dont care about others numbers maybe thats the way they wrote it but in my case comparing numbers is total non-sense, only If I could get my hands on the sort func( cant find it ) and there should be made just a little change and everything will work perfectly ;(. – JohnSmithEr Nov 23 '16 at 13:24

1 Answers1

4

First, if you allocate memory with operator new, you must release it with operator delete[].

Second, when you sort strings instead of values, they are sorted just like strings would do, and here is where your problem lies. You see, 100 is alphabetically less than 2 or 20, that's why it would appear earlier.

Here's the output your program gives. Check this rule out, and you'll see that i'm right.

10 100 110 120 130 140 150 160 20 30 40 50 60 70 80 90

Third, using operator new is discouraged for pretty much anything. You have STL, and you seem to be using it extensively - why not vector?

Fourth, you don't check if anything we write into numbers[i] is actually a number. Think on that.

Fifth, for N being long enough(more than 2^sizeof(size_t)) your problem will NEVER stop due to integer overflow.

Sixth, you don't check for n == 0, and you will ultimately get memory access violation if you enter it.

A fast-right-off-the-bat fix for your problem:

#include <iostream>
#include <algorithm>
#include <string>
#include <vector>

using namespace std;

int main() {
    int examples;
    cin >> examples;
    for (size_t i = 0; i < examples; i++)
    {
        size_t n;
        cin >> n;
        if (n <= 0)
            break;
        vector<string> numbers(n);
        for (size_t i = 0; i < n; i++)
            cin >> numbers[i];

        //here we add a predicate for string checking,
        //which evaluates the length of string
        //before using the usual operator<.

        sort(begin(numbers), end(numbers), [](const string& s1, const string& s2){
            if (s1.length() < s2.length())
                return true;
            if (s2.length() < s1.length())
                return false;
            else
                return (s1 < s2);
        });

        if (n % 2 == 0) {
            cout << numbers[n / 2 - 1];
        }
        else
            cout << numbers[n / 2];
    }

    system("pause");
    return 0;
}

Still, it has a number of problems:

  1. Checking if numbers[i] is actually a number

  2. I'm not sure that predicate I wrote doesn't have bugs - I'm just trying to give you the idea of how it should work.

Steve Thibault
  • 304
  • 2
  • 8
Leontyev Georgiy
  • 1,295
  • 11
  • 24
  • Thank you a lot , for the clearence you made, I did know that the only way was to compare the length of the string but I really had lack of knowledge to rewrite the sort func as you did. As for the other problems they arent that impornt , this is just a homework :) . It is in conditions that it will be always a positive number the n between 1 and 10^6 and the numbers itself always positive from 1 to n^20+ :) – JohnSmithEr Nov 23 '16 at 14:07
  • Check out this post about lambda expressions(that modification to sort that I made), it will give you an idea about what i've done here: http://www.drdobbs.com/cpp/lambdas-in-c11/240168241 – Leontyev Georgiy Nov 23 '16 at 14:20
  • Also, good luck in your training, people here do not like newcomers with sorta easy tasks, and consider them lazy, but they've all been on that road, me included :) – Leontyev Georgiy Nov 23 '16 at 14:22
  • Thanks once again , yes sometimes ppl refuse to help you , because think you dont deserve a help or something like that cause maybe your way to bad or I dont know , in my situation I was aware of the alogorithym and what I need to do, I can also write my self a quicksort and do the same w/o using in-built function , but the task was to be able to use large numbers(string only). I knew that the only way is to compare strings length but as I said lack of knowledge(nobody teaches us) how to rewrite the sort function as you did! – JohnSmithEr Nov 23 '16 at 17:07
  • Just a simplification of the comparison function: `[](const string& s1, const string& s2){ if (s1.size() != s2.size()) { return (s1.length() < s2.length()); } return (s1 < s2); }` – amine Apr 29 '19 at 13:01