Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 17, средняя оценка - 4.82
4ance
1 / 1 / 0
Регистрация: 02.11.2010
Сообщений: 78
#1

Конвертация числа в строку и обратно, условие исключения, разность. - C++

12.11.2010, 18:07. Просмотров 2231. Ответов 27
Метки нет (Все метки)

Здравствуйте! Проблема с задачей:

В четырёхзначном числе все цифры разные и отличны от нуля. если его записать в обратном порядке,
то получится число, на k меньшее первоначального. Найти это число.
Ввод с клавиатуры - разность k.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include "stdafx.h"
#include <conio.h>
#include <locale.h>
#include <stdlib.h> 
#include <iostream>
#include <string>
#include <cstring> 
 
int n1 = 1000, // Начальное значения большего числа 
     n2 = 1000, // Начальное значение меньшего числа
     k;         // Разность - вводимая
     char s[32];    // Массив для конвертация числа в строку
 
 /* itoa:  конвертируем m число символы в s */
 
void itoa(int m, char s[])
 {
     int i = 0;
 
     do {       /* генерируем цифры в обратном порядке */
         s[i++] = m % 10 + '0' ;   /* берем следующую цифру */
     } while ((m /= 10) > 0);     /* удаляем */
     
     s[i] = '\0';
 }
 
int _tmain(int argc, _TCHAR* argv[])
{
  setlocale(LC_ALL, "russian" );  
 
  // Вывод информации о программе
 
  printf("Введите разность между четырёхзначными натуральными числами k\n");
  scanf("%d",&k);
 
  // Решение
 
  for ( int o = 0; n2 < 9999; o++) { // пошаговая инкрементация до конца 4х значных чисел
        if ( n2 / 1000 == 0 || n2 % 1000 / 100 == 0 || n2 % 100 / 10 == 0 || n2 % 10 == 0 ) { // Цифры ненулевые
        n2++;
        }
        else {
            if ( n2 / 1000 != n2 % 1000 / 100 && n2 / 1000 != n2 % 100 / 10 && n2 / 1000 != n2 % 10 && n2 % 1000 / 100 != n2 % 100 / 10 && n2 % 1000 / 100 != n2 % 10 && n2 % 100 / 10 != n2 % 10) { // Цифры различные
                printf("\n\nЧисло n2, прошедшее валидацию = %d\n", n2);
                n1=n2;
                itoa(n1, s); //Перевод в строку с одновременным перевертыванием     
                printf( "atoi выполнена, возвращаемое число = %d", atoi(s)); // Здесь - одна из проблем - переводит строку s в int но сколько я не пытался дальнейшие цифровые операции производить с этим значением не могу
            }
            else {
                n2++;
            }
        }
        n2 = k + n1;  // Здесь вторая и основная проблема - не знаю куда можно
        n1++;         // прицепить зависимость от разности k
  }
 
  // Вывод результата
 
  printf("\n\nНажмите любую клавишу\n");
  _getch();
  return 0;
}
Не сделал только одно - связать основной цикл с разностью k, кроме того не понимаю, почему функция atoi не дает мне производить дальнейшие действия с целыми числами. И самая ли она удобная для операции конвертации?
Поэтому две строчки
C++
1
2
n2 = k + n1;  
n1++;
- не верны

Собственно основной вопрос - куда правильно прицепить разность k? Заранее, спасибо.
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
12.11.2010, 18:07
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Конвертация числа в строку и обратно, условие исключения, разность. (C++):

Конвертация числа в строку - C++
Всем привет, я на форуме только что зарегистрировался и многого не знаю, так что если я создал тему не в том разделе и нарушил что-то, то...

решение задачи,конвертация числа в строку. - C++
дана строка символов,состоящая из произвольных десятичных цифр,разделенных пробелами.вывести на экран числа этой строки в порядке...

Конвертация числа в строку (int to char) - C++
Подскажите, какими процедурами пользоваться, каков синтаксис и формат введенных данных. Скажем есть char row; int t=25, n=9; каким...

Перевод числа в строку и обратно - C++
Какие есть ф-ции для перевода числа в строку и обратно? и можно-ли их будет записывать через getline() ? Например строка hello45who не...

Перевод целого десятичного числа в строку и обратно в десятичное число - C++
перевод целого десятичного числа в строку и обратно в десятичное число, результат вывести в 3 столбика и 20 строк. заранее спасибо)

Конвертация int в char и обратно - C++
Помогите, я запутался... Есть 2 переменных: int a; char b; Допустим a = 0. Нужно преобразовать ее в символ, чтобы b = '0'. ...

27
easybudda
Модератор
Эксперт CЭксперт С++
9695 / 5645 / 963
Регистрация: 25.07.2009
Сообщений: 10,850
12.11.2010, 18:17 #2
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
 
int reverse(int number){
    int rev;
    for ( rev = 0; number; number /= 10 )
        rev = rev * 10 + number % 10;
    return rev;
}
 
int main(void){
    int num, rev;
    
    while ( printf("Number: ") && scanf("%d", &num) == 1 && num ){
        printf("Reverse number: %d\n", ( rev = reverse(num) ));
        printf("Difference: %d\n", rev - num);
    }
    
    return 0;
}
1
4ance
1 / 1 / 0
Регистрация: 02.11.2010
Сообщений: 78
12.11.2010, 19:39  [ТС] #3
Цитата Сообщение от easybudda Посмотреть сообщение
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
 
int reverse(int number){
    int rev;
    for ( rev = 0; number; number /= 10 )
        rev = rev * 10 + number % 10;
    return rev;
}
 
int main(void){
    int num, rev;
    
    while ( printf("Number: ") && scanf("%d", &num) == 1 && num ){
        printf("Reverse number: %d\n", ( rev = reverse(num) ));
        printf("Difference: %d\n", rev - num);
    }
    
    return 0;
}
Хех, я свой быдлокод выдумывал 2 дня, а тут люди и 10 минут не думают как
Ваша программа не сравнима с моей по элегантности, но всё-таки, можно даже на словах - вводимое значение должна быть разность, а не само число. Иначе я совета бы не спрашивал.
C
1
printf("Difference: %d\n", rev - num);
- это я реализовывал 8 часов, но всё-таки реализовал!
А если вводить разность, а 2 числа - неизвестные - пасую
0
norge_goth
62 / 62 / 7
Регистрация: 27.01.2009
Сообщений: 279
13.11.2010, 20:16 #4
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от 4ance Посмотреть сообщение
А если вводить разность, а 2 числа - неизвестные - пасую
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <stdio.h>
#include <stdlib.h>
 
int main(int argc, char *argv[])
{
    int a, b, c, d; // число позиции 4-го числа abcd
    int num, rev_num;
    int difference;
    char line[5];
 
    printf("Please input number difference: ");
 
    while (!scanf("%d", &difference)) printf("it's not a number, try again");
 
    for (a = 1; a <= 9; ++a)
        for (b = 1; b <= 9; ++b) {
            if (b == a) continue;
 
            for (c = 1; c <= 9; ++c) {
                if (c == b || c == a) continue;
 
                for (d = 1; d <= 9; ++d) {
                    if (d == c || d == b || d == a) continue;
                    {
                            // вычисляем основное число
                            sprintf(line, "%d%d%d%d", a, b, c, d);
                            sscanf(line, "%d", &num);
 
                            // вычисляем обратное число
                            sprintf(line, "%d%d%d%d", d, c, b, a);
                            sscanf(line, "%d", &rev_num);
 
                            if ((num - rev_num) == difference) {
                                printf("Number = %d\n", num);
                                system("PAUSE");
                                return 0;
                            }
                    }
                }
            }
        }
 
    printf("Such difference doesn't exists\n");
    system("PAUSE");
    return 0;
    
}
1. Если что непонятно спрашивай
2. Цикл сам приделаешь для кругового набора числа k(чтоб не заканчивался на первом числе)
3
4ance
1 / 1 / 0
Регистрация: 02.11.2010
Сообщений: 78
15.11.2010, 15:34  [ТС] #5
Цитата Сообщение от norge_goth Посмотреть сообщение
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <stdio.h>
#include <stdlib.h>
 
int main(int argc, char *argv[])
{
    int a, b, c, d; // число позиции 4-го числа abcd
    int num, rev_num;
    int difference;
    char line[5];
 
    printf("Please input number difference: ");
 
    while (!scanf("%d", &difference)) printf("it's not a number, try again");
 
    for (a = 1; a <= 9; ++a)
        for (b = 1; b <= 9; ++b) {
            if (b == a) continue;
 
            for (c = 1; c <= 9; ++c) {
                if (c == b || c == a) continue;
 
                for (d = 1; d <= 9; ++d) {
                    if (d == c || d == b || d == a) continue;
                    {
                            // вычисляем основное число
                            sprintf(line, "%d%d%d%d", a, b, c, d);
                            sscanf(line, "%d", &num);
 
                            // вычисляем обратное число
                            sprintf(line, "%d%d%d%d", d, c, b, a);
                            sscanf(line, "%d", &rev_num);
 
                            if ((num - rev_num) == difference) {
                                printf("Number = %d\n", num);
                                system("PAUSE");
                                return 0;
                            }
                    }
                }
            }
        }
 
    printf("Such difference doesn't exists\n");
    system("PAUSE");
    return 0;
    
}
1. Если что непонятно спрашивай
2. Цикл сам приделаешь для кругового набора числа k(чтоб не заканчивался на первом числе)
Так, до sscanf и sprintf, было всё понятно, и судя по развилке - continue - значит продолжать в том случае, если цифры числа будут равны( хотя надо чтобы все раздельные были) так что continue в обратном случае хотел поставить, пока не наткнулся на Sscanf и Sprintf - не знаю что за функции(так же как и аргумент line), щас буду гуглить описание!
Ну и алгоритм для проверки числа на без нулей и различных цифр у меня есть, всё-таки, я что-то ещё сам должен делать, а вы мне почти всю программу дали
Спасибо!

Добавлено через 15 минут
Блин ну цикл для нахождения числа и его обратного офигенный, я его украду)))

Добавлено через 55 минут
continue - пропустить текущую итерацию цикла, ок)

Добавлено через 43 минуты
В результате, только проблему с
C++
1
while (!scanf("%d", &difference)) printf("it's not a number, try again");
решать не стал, да и всё равно препод не придерётся, защиту от дураков нам ещё не рассказыввали (это же второе занятие всего будет), поставил просто сканф принтф и всё.
0
easybudda
Модератор
Эксперт CЭксперт С++
9695 / 5645 / 963
Регистрация: 25.07.2009
Сообщений: 10,850
15.11.2010, 16:49 #6
Цитата Сообщение от norge_goth Посмотреть сообщение
C
1
2
3
4
5
6
7
8
9
...
// вычисляем основное число
sprintf(line, "%d%d%d%d", a, b, c, d);
sscanf(line, "%d", &num);
 
// вычисляем обратное число
sprintf(line, "%d%d%d%d", d, c, b, a);
sscanf(line, "%d", &rev_num);
...
Да, это сто'ит на заметку взять
Цитата Сообщение от norge_goth Посмотреть сообщение
C
1
while (!scanf("%d", &difference)) printf("it's not a number, try again");
А вот тут не комильфо... Функция scanf() возвращает количество присвоенных значений, или EOF в случае ошибки, то есть условие может не сработать при неправильном вводе...
2
norge_goth
62 / 62 / 7
Регистрация: 27.01.2009
Сообщений: 279
15.11.2010, 17:24 #7
Цитата Сообщение от easybudda Посмотреть сообщение
Да, это сто'ит на заметку взять
А вот тут не комильфо... Функция scanf() возвращает количество присвоенных значений, или EOF в случае ошибки, то есть условие может не сработать при неправильном вводе...
да, действительно, условие сработает если только если первый символ окажется не цифрой, например выражение "5a" прокатит, и причем тут бесконечный цикл

scanf() походу проверяет только первый символ, а на второй не смотрит.. тут надо другой подход, но думаю автору поста оно не надо, частичный вариант который усекает неправильное значение только по первому символу могу такое предложить вместо:
C
1
while (!scanf("%d", &difference)) printf("it's not a number, try again");
так:
C
1
2
3
4
5
while (!scanf("%d", &difference)) {
        printf("it's not a number, try again");
        system("PAUSE");
        exit(0);
    }
Добавлено через 5 минут
Цитата Сообщение от 4ance Посмотреть сообщение
continue - пропустить текущую итерацию цикла, ок)
ну я вижу ты сам уже разобрался, так что не спеши вопросы задавать сам поищи, подумай так быстрее научишься, если все-таки есть вопросы - задавай
p.s: и не забываем жать на кнопочку "Спасибо"
1
easybudda
Модератор
Эксперт CЭксперт С++
9695 / 5645 / 963
Регистрация: 25.07.2009
Сообщений: 10,850
15.11.2010, 17:30 #8
norge_goth, обычно как-то так делают:
C
1
2
if ( scanf("%d", &var) != 1 )
  /* всё плохо */
но такой вариант 5а за 5 посчитает. Если нужно прям строго, чтобы число было, лучше strtol() использовать и проверять хвост, который она возвращает...
2
norge_goth
62 / 62 / 7
Регистрация: 27.01.2009
Сообщений: 279
15.11.2010, 19:29 #9
Цитата Сообщение от easybudda Посмотреть сообщение
но такой вариант 5а за 5 посчитает. Если нужно прям строго, чтобы число было, лучше strtol() использовать и проверять хвост, который она возвращает...
ну вот вот так:

C
1
2
3
4
5
6
7
8
9
10
printf("Please input number difference: ");
    scanf("%s", line);
 
    difference = strtol(line, &end, 10);
    if (difference == 0 || *end != 0)
    {
        printf("it's not a number, try again\n");
        system("PAUSE");
        exit(0);
    }
не проверяет только если цифр больше 4, хотя это просто сделать, но мне в лом

вопрос возник прототип ф-ции strtol выглядит так:
C
1
 long int strtol(const char *start, char **end)
параметр end есть указателем на указатель в случае присутствия нецифр он возвращает 0, а в случае если есть не цифры - код символа:

1. если это указатель на указатель значит есть какая-то скрытая(или указатель) переменная на которую он ссылается, но скорее всего переменная ведь он умеет возращать ноль?
2. я сначала объявил end вот так:
C
1
2
3
 
char **end; 
difference = strtol(line, end, 10);
на что мне в месте вызова ф-ции компилятор жаловался на не инициализированный указатель, а когда объявил вот так все норм
C
1
2
char *end; 
difference = strtol(line, &end, 10);
Если можете, объясните почему
1
easybudda
Модератор
Эксперт CЭксперт С++
9695 / 5645 / 963
Регистрация: 25.07.2009
Сообщений: 10,850
15.11.2010, 19:45 #10
norge_goth, вот прям со стишком думаю - разберётесь...
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
 
int main(void){
    char buf[BUFSIZ], * tail;
    long num;
    
    printf("Number: ");
    if ( ! fgets(buf, BUFSIZ, stdin) ){
        fprintf(stderr, "Wrong input!\n");
        exit(1);
    }
    errno = 0;
    num = strtol(buf, &tail, 10);
    if ( errno || *tail != '\n' )
        printf("Too big or too small or not a number at all!\n");
    else
        printf("You have entered %ld\n", num);
    
    exit(0);
}
2
Напильнег
480 / 118 / 10
Регистрация: 30.09.2010
Сообщений: 473
15.11.2010, 21:11 #11
Цитата Сообщение от 4ance Посмотреть сообщение
C++
1
2
3
4
5
6
7
                            // вычисляем основное число
                            sprintf(line, "%d%d%d%d", a, b, c, d);
                            sscanf(line, "%d", &num);
 
                            // вычисляем обратное число
                            sprintf(line, "%d%d%d%d", d, c, b, a);
                            sscanf(line, "%d", &rev_num);
Хм, оригинально. Только вряд ли это будет работать быстрее трех умножений + обвязка...

Ладно, раз пошла такая пьянка, вот вам мой вариантег, в котором задача решается как без умножений, так и без преобразований в строку:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
  num=rev_num=0;
  for (a=1; a<10; a++) {
    num+=1000; rev_num+=1;
    if (1) {
      for (b=1; b<10; b++) {
        num+=100; rev_num+=10;
        if ((b!=a)) {
          for (c=1; c<10; c++) {
            num+=10; rev_num+=100;
            if ((c!=a)&&(c!=b)) {
              for (d=1; d<10; d++) {
                num+=1; rev_num+=1000;
                if ((d!=a)&&(d!=b)&&(d!=c)) {
                  if (rev_num==(num-k)) cout<<a<<b<<c<<d<<endl;
                }
              }
              num-=9; rev_num-=9000;
            }
          }
          num-=90; rev_num-=900;
        }
      }
      num-=900; rev_num-=90;
    }
  }
  num-=9000; rev_num-=9;
1
norge_goth
62 / 62 / 7
Регистрация: 27.01.2009
Сообщений: 279
15.11.2010, 21:29 #12
Цитата Сообщение от Напильнег Посмотреть сообщение
Хм, оригинально. Только вряд ли это будет работать быстрее трех умножений + обвязка...
Ладно, раз пошла такая пьянка, вот вам мой вариантег, в котором задача решается как без умножений, так и без преобразований в строку:
ща освобожусь поковыряю, если честно код выглядит страшно(с точки зрения ясности и удобочитаемости), и потом было бы неплохо замерить скорость выполнения и компиляции моего и вашего кода, у кого какие идеи как это сделать(компилятор mingw)?
0
Напильнег
480 / 118 / 10
Регистрация: 30.09.2010
Сообщений: 473
15.11.2010, 21:49 #13
Цитата Сообщение от norge_goth Посмотреть сообщение
если честно код выглядит страшно(с точки зрения ясности и удобочитаемости)
Просто сам код сложнее. Но будет интересно посмотреть на ваш вариант оформления (Где, <нехорошая женщина>, тут свистящий смайлик?).

Цитата Сообщение от norge_goth Посмотреть сообщение
и потом было бы неплохо замерить скорость выполнения и компиляции моего и вашего кода, у кого какие идеи как это сделать(компилятор mingw)?
Это дело. Только вот компьютер маломощный надо бы найти. И код надо выровнять, а то у меня выводятся все числа, удовлетворяющие условию, а у Вас до первого попадания - конечно так у Вас быстрее будет.
0
norge_goth
62 / 62 / 7
Регистрация: 27.01.2009
Сообщений: 279
15.11.2010, 23:09 #14
Цитата Сообщение от easybudda Посмотреть сообщение
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
 
int main(void){
        char buf[BUFSIZ], * tail;
        long num;
        
        printf("Number: ");
        if ( ! fgets(buf, BUFSIZ, stdin) ){
                fprintf(stderr, "Wrong input!\n");
                exit(1);
        }
        errno = 0;
        num = strtol(buf, &tail, 10);
        if ( errno || *tail != '\n' )
                printf("Too big or too small or not a number at all!\n");
        else
                printf("You have entered %ld\n", num);
        
        exit(0);
}
Разобрался, то есть при объявлении указателю выделяется память, назначается адрес, и потому адрес указателя можно передавать в ф-цию, а значение нет, так как оно не инициализировано(неопределено)
блин указатели реально мозги ломают, слава Богу хоть вся мозаика под названием указатель собираться начинает
0
easybudda
Модератор
Эксперт CЭксперт С++
9695 / 5645 / 963
Регистрация: 25.07.2009
Сообщений: 10,850
15.11.2010, 23:18 #15
norge_goth, указатель - по сути целочисленная переменная, под которую выделяется память и у которой есть свой адрес. Вот как-раз адрес переменной-указателя заносится вторым параметром в strtol().
2
15.11.2010, 23:18
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
15.11.2010, 23:18
Привет! Вот еще темы с ответами:

Конвертация qint64 в int и обратно - C++
Здравствуйте, делаю программу и возникла необходимость конвертации qint64 в int и обратно. Как можно это делать? гугление не помогло

Конвертация времени в американский формат и обратно - C++
есть задача: создать класс Time, в котором реализованы операции сложения, вычитания, сравнения, введения и выведения на екран. Возможность...

Конвертация wchar_t в число целого типа. Обработка исключения - C++
Конвертирую считываемые данные с Экселя в число типа int,для дальнейшей проверки вхождения в массив. buff содержит значение 12345qwe ...

Преобразование класса в строку и обратно - C++
Всем доброго времени суток. Пишу курсач на плюсах (простенький чат). Обязательным условием является использование классов(плюсы все таки)....


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru