Вам задано целое число 51234
(скажем), нам нужно отсортировать цифры номера, который будет выводиться 12345
.Сортировка цифр целого числа
Как это сделать без использования массива?
Вам задано целое число 51234
(скажем), нам нужно отсортировать цифры номера, который будет выводиться 12345
.Сортировка цифр целого числа
Как это сделать без использования массива?
Вы можете использовать цикл и % 10
для извлечения каждой цифры. Внешний цикл от 0 до 9 может использоваться для проверки наличия цифры. Если он существует, распечатайте его.
В псевдокоде:
n = integer // 51234
FOR digit = 0 TO 9
temp = n
REPEAT
IF temp % 10 = digit THEN PRINT digit
temp /= 10
UNTIL temp = 0
Edit: Этот тест в GCC показывает, что он обрабатывает нули и повторяющиеся цифры:
$ cat sortdigits.c
#include <stdio.h>
main() {
int n,digit,temp;
n = 43042025;
for (digit=0;digit<9;digit++)
for (temp=n;temp>0;temp/=10)
if (temp%10==digit) printf("%d",digit);
printf("\n");
}
$ ./sortdigits
00223445
+1 Я согласен с этим :) Псевдокода не понадобится, хотя :) –
Красивая ... Хм ... в некотором роде. –
@ Паскаль: Наверное. Если вы хотите перебирать число в 10 раз вместо одного. Это экономит память, хотя :-). –
Разделить на 10 заданных целых чисел в цикле. Распечатайте напоминание на каждой итерации.
Или «сортировка» означает, что здесь? Для реальной сортировки вам понадобятся две петли. Один из них будет от 0 до 9. Еще один будет описан ранее.
int main()
{
int x = 0;
cin >> x;
for (int l = 0; l < 10; ++l)
{
int rem = x % 10;
int tx = x/10;
while (rem || tx)
{
if (rem == l) cout << rem;
rem = tx % 10;
tx = tx/10;
}
}
cout << endl;
}
Общий обзор:
Единственный потенциально сложный бит может быть правильно обрабатывать нули - вам не нужно слишком много, и вам нужно обработать край, где вход нуль правильно.
Фактическая реализация остается в качестве упражнения ...
Easy:
#include <stdio.h>
#include <stdlib.h>
static void pput(int n, int c)
{
int i;
for (i=0; i < n; ++i) putchar(c);
}
int main(int argc, char *argv[])
{
int zeros = 0;
int ones = 0;
int twos = 0;
int threes = 0;
int fours = 0;
int fives = 0;
int sixes = 0;
int sevens = 0;
int eights = 0;
int nines = 0;
long num = 0;
if (argc > 1) {
char *eptr;
num = strtol(argv[1], &eptr, 0);
if (*eptr) {
fprintf(stderr, "Invalid number: '%s', using 0.\n", argv[1]);
num = 0;
}
}
do {
switch (num % 10) {
case 0: ++zeros;
break;
case 1: ++ones;
break;
case 2: ++twos;
break;
case 3: ++threes;
break;
case 4: ++fours;
break;
case 5: ++fives;
break;
case 6: ++sixes;
break;
case 7: ++sevens;
break;
case 8: ++eights;
break;
case 9: ++nines;
break;
default:
break;
}
} while ((num /= 10));
pput(zeros, '0');
pput(ones, '1');
pput(twos, '2');
pput(threes, '3');
pput(fours, '4');
pput(fives, '5');
pput(sixes, '6');
pput(sevens, '7');
pput(eights, '8');
pput(nines, '9');
putchar('\n');
return 0;
}
Компиляция и запуск:
$ gcc -Wextra -Wall -ansi -pedantic -Wfloat-equal -Wundef -Wshadow \
-Wpointer-arith -Wcast-qual -Wcast-align -Wstrict-prototypes \
-Wswitch-default -Wswitch-enum -Wstrict-overflow=5 \
-Wdeclaration-after-statement -Wwrite-strings -Wconversion \
-Waggregate-return -Wunreachable-code a.c
$ ./a.out
0
$ ./a.out 54321
12345
$ ./a.out 9834346
3344689
$ ./a.out hello
Invalid number: 'hello', using 0.
0
:-)
Другое решение, не используя массивов и довольно коротких строк на линии:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
int main(int argc, char *argv[])
{
long num = 0;
int i;
size_t *freq;
if (argc > 1) {
char *eptr;
num = strtol(argv[1], &eptr, 0);
if (*eptr || errno == ERANGE) {
fprintf(stderr, "Invalid number: '%s', using 0.\n", argv[1]);
num = 0;
}
}
if ((freq = calloc(10, sizeof *freq)) == NULL) {
perror("malloc failure");
return EXIT_FAILURE;
}
do
++freq[num % 10];
while ((num /= 10));
for (i=0; i < 10; ++i) {
size_t j;
for (j=0; j < freq[i]; ++j)
putchar(i + '0');
}
putchar('\n');
free(freq);
return EXIT_SUCCESS;
}
Да, я знаю о «правильном» решении. Но почему бы не использовать массивы для этой проблемы? Как один из комментаторов сказал, что я не хотел бы работать в компании, которая не позволит мне использовать массивы в С.
Howz that easy ?? !! Все эти строки действительно необходимы? : O –
@nthgreek: Я хочу сказать, что вопрос действительно плохой. Почему бы вам не использовать массив здесь? –
Использование массива сделает так просто, что даже ребенок может это сделать! : P –
// Bubblesort
long sortNum(long n) {
while (true) {
long a = n % 10, p = 9;
bool s = false;
for (long r = n/10; r; r/= 10) {
long b = r % 10;
if (a < b) {
n -= p * (b - a);
s = true;
} else a = b;
p *= 10;
}
if (!s) return n;
}
}
#include <iostream>
int main(int argc, char **argv) {
if (argc > 1) {
long n = strtol(argv[1], 0, 0);
std::cout << "Unsorted: " << n << std::endl;
n = sortNum(n);
std::cout << "Sorted: " << n << std::endl;
}
return 0;
}
$ g++ -Wall -Wextra bubble-int.cpp && ./a.exe 183974425
Unsorted: 183974425
Sorted: 123445789
Умный - я даже не выглядел близко к этому, пока я не увидел комментарий Стива Джессопа в другом ответе. Для обработки нулей требуется немного. Все еще очень умно. –
Спасибо. «Ответ на трюк» на трюк. Если бы кто-то действительно дал мне этот ответ в интервью, я бы спросил: «Почему так сложно? Почему бы не использовать std :: map?» Хорошо иметь людей, которые ** могут делать такие вещи, но также и знать, когда лучше не делать этого. – Dan
Красивые.Избегает преобразования строк (обычная вещь, которую люди, похоже, предлагают для сортировки цифр), и имеет то преимущество, что отсортированный номер доступен для дальнейшего использования. – Tony
Можно попробовать что-то вроде вставки рода. По существу, создайте новый номер, взяв одну цифру из старой за раз и положив ее в нужное место. Что-то вроде этого.
while(num!=0){
dig = num%10; // get the last digit
if(newNum=0) newNum+=dig;
else{
newNumTemp = 0; flag =1;i =1;
while (newNum != 0){
Newdig = newNum%10;
if(flag){
if (Newdig >= dig)
{NewNumTemp = Newdig*(10^i)+ NewNumTemp; }
else { flag=0; NewNumTemp = dig*(10^i) +NewNumTemp; i++;NewNumTemp = Newdig* (10^i)+ NewNumTemp;}
} // end of outer if
i++;
newNum/=10;
} // end of while
newNum= newNumTemp;
}// end of else
num/=10;
}// end of outer while
извините за формат. Как вставить фрагмент кода? –
Любая строка, начинающаяся с четырех пробелов, остается нетронутой. Нажать на "?" в правом верхнем углу окна справки. –
@Alok: Спасибо за отзыв –
Вам не нужно написать программу на всех, просто сделать это с помощью команд оболочки:
echo "51234" | sed 's+\(.\)+\1\n+g' | sort | tr -d '\n'
50 лет назад это будет считаться высокоуровневым программированием. :-) – Ken
Создание интерфейса контейнера над междунаром (что-то вроде вектора), где оператор ссылается i-я десятичная цифра. Вам придется определять итераторы и другие вещи. Затем вызовите std :: sort. ;)
Конечно массивы, но у нас есть лучший контейнер в любом случае:
void foo(unsigned i) {
std::set<char> digits;
do {
digits.insert(`0` + i % 10);
i /= 10;
while(i!=0);
}
Используйте multiset
, если ваш вклад включает в себя номера, как 887
, которые должны быть напечатаны в 788
Я думаю, что если массивы не разрешены, то на самом деле любые контейнеры не допускаются. –
Я не хочу работа для компании, которая не позволяет мне использовать массив. – Karl
@Karl: массивы не из дешевых, и с финансовым кризисом понятно, что они не хотят их использовать! :-) –
Я бы использовал карту из злобы: p – meagar