I have to write a code which sort digits in one entered number.
For example: input: 4713239
output: 1233479
It doesn't work properly when I enter repeating digits(like 33) when I have the last loop as FOR:
for(int j = 0; j < arr[i]; j++) // in this loop my output is: 123479.
When I change this loop from FOR to WHILE it works properly.
It means:
while(arr[i]) // and the number is sorted correctly (1233479)
True be told, I don't know what is the difference between these operations in this code.
Why FOR loop doesn't work properly? Could somebody explain me this?
I wrote a code:
int sort(int arg)
{
int var, score = 0;
int arr[10] = {0};
for(int i = 0; i < 10; i++)
{
var = arg % 10;
arr[var]++;
arg = arg / 10;
}
for(int i = 0; i < 10; i++)
{
for(int j = 0; j < arr[i]; j++) //while(arr[i]) --> works correctly
{
score = score * 10 + i;
arr[i]--;
}
}
return score;
}
You modify both arr[i] and j, therefore the loop will end too fast when both are part of the comparison.
for(int j = 0; j < arr[i]; j++) // increase j, compare with arr[i]
{
score = score * 10 + i;
arr[i]--; // decrease arr[i]
}
Related
I am creating a sort selecting that puts the max number to the right. I think i have it mostly done and when i execute the code it works but it does not sort the first two numbers in order from smallest to largest.
When I compile I get 2,1,4,7,9,12,99
int n = 7;
int list[] = { 9, 2, 99, 4, 1, 12, 7};
int maxIndex = n - 1;
for (int i = 0; i < maxIndex-1; i++)
{
int maxNum = i;
for (int j = i+1; j < n; j++)
{
if (list[j] > list[maxNum])
{
maxNum = j;
}
int temp = list[j];
list[j] = list[maxNum];
list[maxNum] = temp;
}
}
Im not too sure if its the for function or it has to do with the swap that i have but i dont think its the swap or else the it wouldn't order the other numbers.
So there are a few problems. The first is that your loop limit is incorrect
for (int i = 0; i < maxIndex-1; i++)
should be
for (int i = 0; i < n-1; i++)
You can get rid of the maxIndex variable.
Second your swap is in the wrong place and you swap the wrong elements. You are supposed to swap the maximum value with the current value, so the swap should go after the j loop and not inside it. It's only after the j loop completes that you know what the maximum value is. Plus what you swap is list[i] (the current value) with list[maxNum] (the maximum value). Like this
int maxNum = i;
for (int j = i+1; j < n; j++)
{
if (list[j] > list[maxNum])
{
maxNum = j;
}
}
int temp = list[i];
list[i] = list[maxNum];
list[maxNum] = temp;
Incidentally I don't like the variable name maxNum because it is not a number it's an index. Maybe maxNumIndex would be a better name?
We can define the term 'value of a name' as the average position of
the letters in the name, calculating 'A' as 1, 'B' as 2, 'C' as 3, and
so on. The value of "BOB" would be (2 + 15 + 2)/ 3 = 6. According to
this value, the names will be arranged from the smallest towards the
biggest in the output. When two or more names have the same value,
the name which is in the first position in the original list (the
first one the user inputs) should show up first in the sorted list
(the output).
Input In the first line we have an integer N (1 <= N <= 100), which is
the number of names. In every of the N lines we have one name ([A-Z],
no empty spaces). Names contain 1 - 200 letters.
Output Print out the sorted list (one name in a line).
Test-case
Input: 3 BOB AAAAAAA TOM Output: AAAAAAA BOB TOM
I tried something, and the code seemed to work, I just had a problem with the output. I couldn't find a way to arrange the names with the same value, according to their position in the original list. Here's the other test-case I tried, but didn't figure out:
Input:
10
COSOPYILSPKNKZSTUZVMEERQDL
RRPPNG
PQUPOGTJETGXDQDEMGPNMJEBI
TQJZMOLQ
BKNGFEJZWMJNJLSTUBHCFHXWMYUPZM
YNWEPZKNBOOXNZVWKIUS
LV
CJDFYDMYZVOEW
TMHEJLIDEHT
KGTGFIFWYTKPWTYQQPGKRRYFXN
Output:
TMHEJLIDEHT
PQUPOGTJETGXDQDEMGPNMJEBI
BKNGFEJZWMJNJLSTUBHCFHXWMYUPZM
CJDFYDMYZVOEW
RRPPNG
COSOPYILSPKNKZSTUZVMEERQDL
KGTGFIFWYTKPWTYQQPGKRRYFXN
TQJZMOLQ
YNWEPZKNBOOXNZVWKIUS
LV
My output:
TMHEJLIDEHT
PQUPOGTJETGXDQDEMGPNMJEBI
CJDFYDMYZVOEW // these two
BKNGFEJZWMJNJLSTUBHCFHXWMYUPZM // should be arranged with their places switched
RRPPNG
COSOPYILSPKNKZSTUZVMEERQDL
KGTGFIFWYTKPWTYQQPGKRRYFXN
TQJZMOLQ
YNWEPZKNBOOXNZVWKIUS
LV
#include <iostream>
#include <string>
using namespace std;
int main() {
int N;
cin >> N;
string words[N];
int res[N];
for (int i = 0; i < N; i++) {
int sum = 0;
int value = 0;
int temp = 0;
string word;
cin >> words[i];
word = words[i];
for (int j = 0; j < word.length(); j++) {
sum += (int)word[j] - 64;
}
value = sum / word.length();
res[i] = value;
}
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (res[i] < res[j]) {
swap(res[i], res[j]);
swap(words[i], words[j]);
}
}
}
for (int i = 0; i < N; i++) {
cout << words[i] << endl;
}
return 0;
}
string words[N];
int res[N];
This here is not valid C++, you can not size a stack array using a runtime variable, although some compilers might support such a feature. You might use say std::vector instead, which behaves much like an array.
vector<string> words;
vector<int> res;
for (int i = 0; i < N; i++) {
int sum = 0;
int value = 0;
int temp = 0;
string word;
cin >> word;
words.push_back(word);
for (int j = 0; j < word.length(); j++) {
sum += (int)word[j] - 64;
}
value = sum / word.length();
res.push_back(value);
}
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (res[i] < res[j]) {
swap(res[i], res[j]);
swap(words[i], words[j]);
}
}
}
The ordering is because your sorting algorithm is not stable. Stable means that items with equal values will maintain the same order relative to each other.
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (res[i] < res[j]) {
swap(res[i], res[j]);
swap(words[i], words[j]);
}
}
}
What you have is very close to bubble sort, which is stable.
for (int i = 0; i < N; i++) {
for (int j = 0; j < N - i - 1; j++) { // i elements sorted so far
if (res[j] > res[j + 1]) {
swap(res[j], res[j + 1]);
swap(words[j], words[j + 1]);
}
}
}
C++ also provides a stable sort in <algorithm>, but it can't function directly on two arrays like this unfortunately, one option is to compute the value on the fly, another could be to make a class holding both items and sort that, or another to sort the indices.
std::stable_sort(words.begin(), words.end(), [&](auto &a, auto &b)
{
int suma = 0, sumb = 0; // better yet, make a "int value(const string &str)" function.
for (int j = 0; j < a.length(); j++) {
suma += (int)a[j] - 64;
}
for (int j = 0; j < b.length(); j++) {
sumb += (int)b[j] - 64;
}
int valuea = suma / a.length();
int valueb = sumb / b.length();
return valuea < valueb;
});
A class containing both items is pretty straight forward, for indices, make a 3rd array and sort that.
vector<size_t> indices;
...
string word;
cin >> word;
indices.push_back(words.size());
words.push_back(word);
...
std::stable_sort(indices.begin(), indices.end(), [&](auto a, auto b){ return res[a] < res[n]; });
for (int i = 0; i < N; i++) {
cout << words[indices[i]] << endl;
}
A possible solution could be order the result array during construction.
When you add the words in the result array, use the result obtained to add the word in the right place. In this way you can check if exist already the same value and add the new word after the previous with the same value.
After reading the next word use insertion sort (wiki) which is stable
read word
calculate value
insert in a right place in the array
go to 1 until i < N otherwise print out
Doesn't require additional sorting procedure.
in python:
def sort_list(list1, list2):
zipped_pairs = zip(list2, list1)
z = [x for _, x in sorted(zipped_pairs)]
return z
times = int(input())
entries = []
ordered = []
for x in range(times):
entries.append(input())
for x in entries:
chars = []
for y in x:
chars.append(ord(y) - 96)
ordered.append(sum(chars))
print(sort_list(entries,ordered))
If you use a std::multimap<int, std::string>, there would be no need to sort, as the key would already serve as the sorting criteria.
Here is a solution using std::multimap:
#include <string>
#include <numeric>
#include <iostream>
#include <sstream>
#include <map>
// Test data
std::string test = "10\n"
"COSOPYILSPKNKZSTUZVMEERQDL\n"
"RRPPNG\n"
"PQUPOGTJETGXDQDEMGPNMJEBI\n"
"TQJZMOLQ\n"
"BKNGFEJZWMJNJLSTUBHCFHXWMYUPZM\n"
"YNWEPZKNBOOXNZVWKIUS\n"
"LV\n"
"CJDFYDMYZVOEW\n"
"TMHEJLIDEHT\n"
"KGTGFIFWYTKPWTYQQPGKRRYFXN\n";
int main()
{
std::istringstream strm(test);
// Read in the data
std::multimap<int, std::string> strmap;
int N;
strm >> N;
std::string word;
for (int i = 0; i < N; ++i)
{
strm >> word;
// get the average using std::accumulate and divide by the length of the word
int avg = std::accumulate(word.begin(), word.end(), 0,
[&](int total, char val) { return total + val - 'A' + 1; }) / word.length();
// insert this value in the map
strmap.insert({ avg, word });
}
// output results
for (auto& w : strmap)
std::cout << w.second << "\n";
}
Output:
TMHEJLIDEHT
PQUPOGTJETGXDQDEMGPNMJEBI
BKNGFEJZWMJNJLSTUBHCFHXWMYUPZM
CJDFYDMYZVOEW
RRPPNG
COSOPYILSPKNKZSTUZVMEERQDL
KGTGFIFWYTKPWTYQQPGKRRYFXN
TQJZMOLQ
YNWEPZKNBOOXNZVWKIUS
LV
The std::accumulate is used to add up the values to get the average.
Or just order them in the end (You won't need the 2nd array):
for (int i = 0; i < N; i++) {
for (int j = i + 1; j < N; j++) {
int sumA = 0, sumB = 0;
for (int k = 0; k < words[i].size(); k++)
sumA += words[i][k] - 'A' + 1;
for (int k = 0; k < words[j].size(); k++)
sumB += words[j][k] - 'A' + 1;
if (sumA / words[i].size() > sumB / words[j].size())
swap(words[i], words[j]);
}
}
As they shown above, it's way better to use a vector to store your data.
I am trying to implement the Counting Sort in C++ without creating a function. This is the code that I've written so far, but the program doesn't return me any values. It doesn't give me any errors either. Therefore, what is wrong?
#include <iostream>
using namespace std;
int main()
{
int A[100], B[100], C[100], i, j, k = 0, n;
cin >> n;
for (i = 0; i < n; ++i)
{
cin >> A[i];
}
for (i = 0; i < n; ++i)
{
if (A[i] > k)
{
k = A[i];
}
}
for (i = 0; i < k + 1; ++i)
{
C[i] = 0;
}
for (j = 0; j < n; ++j)
{
C[A[j]]++;
}
for (i = 0; i < k; ++i)
{
C[i] += C[i - 1];
}
for (j = n; j > 0; --j)
{
B[C[A[j]]] = A[j];
C[A[j]] -= 1;
}
for (i = 0; i < n; ++i)
{
cout << B[i] << " ";
}
return 0;
}
It looks like you're on the right track. You take input into A, find the largest value you'll be dealing with and then make sure you zero out that many values in your C array. But that's when things start to go wrong. You then do:
for (i = 0; i < k; ++i)
{
C[i] += C[i - 1];
}
for (j = n; j > 0; --j)
{
B[C[A[j]]] = A[j];
C[A[j]] -= 1;
}
That first loop will always go out of bounds on the first iteration (C[i-1] when i=0 will be undefined behavior), but even if it didn't I'm not sure what you have in mind here. Or in the loop after that for that matter.
Instead, if I were you, I'd create an indx variable to keep track of which index I'm next going to insert a number to (how many numbers I've inserted so far), and then I'd loop over C and for each value in C, I'd loop that many times and insert that many values of that index. My explanation may sound a little wordy, but that'd look like:
int indx = 0;
for(int x = 0; x <= k; x++) {
for(int y = 0; y < C[x]; y++) {
B[indx++] = x;
}
}
If you replace the two loops above with this one, then everything should work as expected.
See a live example here: ideone
I am trying to fill an array of 52 with the numbers 0 - 12. Once it hits 12, it needs to go back to 0 - 12 again. You might have already guessed it's a deck of cards. My code is below and doesn't work. It prints 0 - 12 one time, but then prints the address of the array I believe for the remainder of the iterations left.
#include<iostream>
#include<string>
using namespace std;
int main()
{
int myArray[52];
for (int j = 0; j < 4; j++)
{
for (int i = 0; i < 13; i++)
{
myArray[i] = i;
}
}
for (int k = 0; k < 52; k++)
{
cout << myArray[k] << endl;
}
//system("pause");
return 0;
}
Can someone please help me with this brain fart?
int myints[52];
for (int idx = 0; idx < 52; idx++)
{
myints[idx] = idx % 13;
}
Modulus of 13 will range from 0 to 12.
You're indexing the same first 12 elements of the array in the inner loop for every iteration of the outer loop.
Try changing it to something like this
for (int j = 0; j < 4; j++)
{
for (int i = 0; i < 13; i++)
{
myArray[i + 13 * j] = i;
}
}
That is my function:
int main() {
double data[100];
int num;
cout<<"num= ";
cin>>num;
for(int i = 1; i <= num; i++) {
cout<<i<<" element = ";
cin>>data[i];
}
Sort(data, num);
for (int i = 1; i <= num; i++) {
cout<<data[i]<<endl;
}
return 0;
}
void Sort(double data[], int n) {
int i,j,k;
double min;
for(i = 0; i < n-1; i++) {
k = i;
min = data[k];
for(j = i+1; j < n; j++)
if(data[j] < min) {
k = j;
min = data[k];
}
data[k] = data[i];
data[i] = min;
}
}
if I write for exp. three elements: 8,9,1 again cout 8,9,1?
for(int i = 1; i <= num; i++) { // WRONG
I think you mean:
for(int i = 0; i < num; i++) { // RIGHT
Arrays in C are 0-indexed remember.
Your sorting function is fine. The only problem is that you enter elements at positions 1 through n, inclusive, while you should use 0 through n-1, inclusive, in both loops of the main() function.
If you need to print numbers 1 through n, use
cout<<(i+1)<<" element = ";
You should get used of the 0 index begin in the for loop
for(int i = 0; i < N; ++i)
so fixing these two index errors will make your code run properly.
the reason is:
if you write data to data[] using 1 as the begining, your data array's first item will be a random number:
if you insert 3 elements, the array will be like this:
data[0] = ??? // maybe a very very big number
data[1] = 8
data[2] = 9
data[3] = 1
and in your Sort function, your index begins at 0 and ends before num, that means your code would only sort data[0], data[1], data[2].
if you use: num = 3, 3 2 1 as your input data for the origin code you could see that 3 and 2 is sorted
I guess your Sort code is googled from somewhere, please try to understand it.
Good online algorithm course: https://www.coursera.org/course/algs4partI
a very good algorithm online book: http://algs4.cs.princeton.edu/home/
btw, for(j = i+1; j < n; j++) in the Sort function would be better if it has { } braces.