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

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

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

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

12.11.2010, 18:07. Просмотров 2223. Ответов 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
4ance
1 / 1 / 0
Регистрация: 02.11.2010
Сообщений: 78
16.11.2010, 11:18  [ТС] #16
Цитата Сообщение от norge_goth Посмотреть сообщение
ну я вижу ты сам уже разобрался, так что не спеши вопросы задавать сам поищи, подумай так быстрее научишься, если все-таки есть вопросы - задавай
p.s: и не забываем жать на кнопочку "Спасибо"
Всем поставил +1, правда не вкурил про указатели указателей (обычных указателей недостаточно чтоле ), но сейчас время печатать следующий быдлокод!
0
norge_goth
62 / 62 / 7
Регистрация: 27.01.2009
Сообщений: 279
16.11.2010, 11:50 #17
Цитата Сообщение от 4ance Посмотреть сообщение
Всем поставил +1, правда не вкурил про указатели указателей (обычных указателей недостаточно чтоле ), но сейчас время печатать следующий быдлокод!
нет не достаточно, например когда надо выделить динамически память для двумерного массива, одинарного указателя недостаточно(так как в Си да и в С++ многомерные массивы - это массивы массивов) - посмотри эту тему Перераспределение динамической памяти
есть еще ф-ция
C
1
long int strtol(const char *start, char **end)
попробуй проанализировать на примере выше(пост №14) почему она требует указатель на указатель и почему одинарного указателя будет мало
и это еще не весь список например если создавать 3-мерный динамический массив, то попребуется указатель вида
C
1
int*** ptr;
0
4ance
1 / 1 / 0
Регистрация: 02.11.2010
Сообщений: 78
16.11.2010, 12:05  [ТС] #18
Кстати, насчёт массивов:
C++
1
char line[5];
почему для 4-х значного числа нужен массив с пятью ячейками? Или можно задать массив с 4мя ячейками и программа ругаться не будет?
0
norge_goth
62 / 62 / 7
Регистрация: 27.01.2009
Сообщений: 279
16.11.2010, 12:23 #19
Цитата Сообщение от 4ance Посмотреть сообщение
почему для 4-х значного числа нужен массив с пятью ячейками? Или можно задать массив с 4мя ячейками и программа ругаться не будет?
последний символ надо резервировать для для символа окончания строки, который компилятор сам добавляет в конец каждой С-строки, например:
C
1
2
3
char ch[5];
strcpy(ch, "word");
printf("%s\n", ch);
компилятор запишет строку ch как "word\0" этот символ надо чтобы знать когда строка заканчивается, поэтому надо резервировать на 1 символ больше
Ругаться не будет, но последствия могут быть не предсказуемыми

Добавлено через 1 минуту
Цитата Сообщение от 4ance Посмотреть сообщение
почему для 4-х значного числа нужен массив с пятью ячейками?
кстати, это написано в любой книги по Си, почитай Шилдта например, знать такие вещи очень важно
1
4ance
1 / 1 / 0
Регистрация: 02.11.2010
Сообщений: 78
16.11.2010, 13:32  [ТС] #20
Цитата Сообщение от norge_goth Посмотреть сообщение
кстати, это написано в любой книги по Си, почитай Шилдта например, знать такие вещи очень важно
Спасибо, почитаю, сейчас мне препод дал только статью Андрея Богатырёва "Руководство полного идиота по программированию ( на языке Си)"
0
Напильнег
480 / 118 / 10
Регистрация: 30.09.2010
Сообщений: 473
17.11.2010, 22:33 #21
Цитата Сообщение от norge_goth Посмотреть сообщение
было бы неплохо замерить скорость выполнения и компиляции моего и вашего кода, у кого какие идеи как это сделать(компилятор mingw)?
Зачем замерять скорость компиляции, представить не могу, а скорость работы... Нашел я таки способ загрузить серого даже на современном компьютере, вот так (Visual C++):
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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#include "stdafx.h"
 
#include <stdio.h>
#include <windows.h>
 
int count_for_k_Etalon00(int k)
{
  int count=0;
  
  int a, b, c, d;
  int diff;
 
  for (a=1; a<10; a++)
    for (b=1; b<10; b++)
      for (c=1; c<10; c++)
        for (d=1; d<10; d++)
          if ((b!=a)&&(c!=a)&&(c!=b)&&(d!=a)&&(d!=b)&&(d!=c)) {
            diff=(((a*10+b)*10+c)*10+d)-(((d*10+c)*10+b)*10+a);
            if (diff==k) {
              //printf("%d%d%d%d\n", a, b, c, d);
              count++;    
            }
          }
 
  return count;
}
 
int count_for_k_norge_goth00(int k)
{
    int count=0;
 
    int a, b, c, d; // число позиции 4-го числа abcd
    int num, rev_num;
    int difference;
    char line[5];
 
    difference=k;
 
    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) {
                                count++;  
                            }
                    }
                }
            }
        }
 
    return count;
}
 
int count_for_k_Napilneg00(int k)
{
  int count=0;
  
  int num, rev_num; 
  int a, b, c, d;
 
  num=rev_num=0;
  for (a=1; a<10; a++) {
    num+=1000; rev_num+=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)) count++;
                }
              }
              num-=9; rev_num-=9000;
            }
          }
          num-=90; rev_num-=900;
        }
      }
      num-=900; rev_num-=90;
    }
  }
  num-=9000; rev_num-=9;
 
  return count;
}
 
int main()
{
  char s[128];
 
  int c4k[10000];
  int k;
 
  int start, end;
 
//Filling by etalon values
  for (k=0; k<10000; k++) {
    c4k[k]=count_for_k_Etalon00(k);
  }
 
//Strictly testing
  for (int nfunc=0; nfunc<=2; nfunc++) {
    int (*f)(int);
 
    switch (nfunc) {
      case 0: 
        printf("%20s: ", "Etalon00");
        f=&count_for_k_Etalon00;
        break;
      case 1: 
        printf("%20s: ", "norge_goth00");
        f=&count_for_k_norge_goth00;
        break;
      case 2: 
        printf("%20s: ", "Napilneg00");
        f=&count_for_k_Napilneg00;
        break;
      default:
        printf("Error func num\n");
        goto quit;
    }
  
    start=GetTickCount();
  
    for (k=0; k<10000; k++) {
      if ((*f)(k)!=c4k[k]) {
        printf("error for k=%d\n", k);
        goto next;
      }
    }
 
    end=GetTickCount();
          
    printf("%.3f sec\n", (end-start)/1000.0);
 
  next:
    ;
  }
 
quit:
  gets(s);
  
  return 0;
}
В качестве эталона для сравнения взята самая тупая реализация, в которой все проверки и подсчеты происходят во внутреннем цикле, причем считаются числа с помощью умножений по схеме Горнера. Вот результат (надо заметить - ошеломляющий):
C++
1
2
3
            Etalon00: 0.953 sec
        norge_goth00: 214.172 sec
          Napilneg00: 0.515 sec
Итаг, код любителя делать замечания по поводу оформления кода в полной ж..., что в общем-то было предсказуемо, хоть и не до такой степени. Мой код, правда, не дает ожидаемого принципиального выигрыша, но у него есть резерв повышения эффективности, поработаем еще.
0
4ance
1 / 1 / 0
Регистрация: 02.11.2010
Сообщений: 78
19.11.2010, 11:04  [ТС] #22
Почему такая разница в быстродействии?
0
silent_1991
Эксперт С++
4984 / 3041 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
19.11.2010, 11:23 #23
Думаю, у norge_goth код проигрывает за счёт sprintf'ов и sscanf'ов... Если их заменить на стандартные умножения-сложения - всё будет ок.
0
Напильнег
480 / 118 / 10
Регистрация: 30.09.2010
Сообщений: 473
19.11.2010, 12:19 #24
Цитата Сообщение от silent_1991 Посмотреть сообщение
Если их заменить на стандартные умножения-сложения- всё будет ок.
Что значит если - будет? А count_for_k_Etalon00 что делает?
0
norge_goth
62 / 62 / 7
Регистрация: 27.01.2009
Сообщений: 279
20.11.2010, 22:15 #25
Цитата Сообщение от Напильнег Посмотреть сообщение
Итаг, код любителя делать замечания по поводу оформления кода в полной ж..., что в общем-то было предсказуемо, хоть и не до такой степени. Мой код, правда, не дает ожидаемого принципиального выигрыша, но у него есть резерв повышения эффективности, поработаем еще.
ты наверно перепутал свой быдло-код с моим когда тестил, вот что сказал gc++:
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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
 
long int funcBy_norge();
long int funcBy_Napilneg();
 
const int endSearch = 10000, startSearch = 1000;
 
int main(int argc, char *argv[])
{
 
    long int result_norge, result_Napilneg;
 
    printf("\nFunction by norge\n");
    result_norge = funcBy_norge();
    printf("\nFunction by Napilneg\n");
    result_Napilneg = funcBy_Napilneg();
 
    printf("\n Function by norge -> Time Elapsed %ld ms \n", result_norge);
 
    printf("\n Function by Napilneg -> Time Elapsed %ld ms \n", result_Napilneg);
 
    system("PAUSE");
    
    return 0;
 
}
 
long int funcBy_norge()
{
 
    DWORD StartTime, EndTime;
    StartTime = GetTickCount();
 
    int a, b, c, d; // число позиции 4-го числа abcd
    int num, rev_num;
    int difference;
    char line[5], *end;
 
    for(int j = startSearch; j < endSearch; ++j)
    {
        difference = j;
 
    //printf("\n%d\n", *end);
 
    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");
 
    //printf("%d\n", sizeof(long long double));
    }
 
    EndTime = GetTickCount();
    long int times = EndTime - StartTime;
 
    return times;
}
 
long int funcBy_Napilneg()
{
    DWORD StartTime, EndTime;
    StartTime = GetTickCount();
 
    int count=0;
 
      int num, rev_num;
      int a, b, c, d;
 
      for (int k = startSearch; k < endSearch; k++) {
       num=rev_num=0;
      for (a=1; a<10; a++) {
        num+=1000; rev_num+=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))
                                count++;
                                printf("\n number %d \n", num);
                        }
                    }
 
                    num-=9; rev_num-=9000;
                    }
              }
 
              num-=90; rev_num-=900;
            }
          }
          num-=900; rev_num-=90;
        }
      }
      num-=9000; rev_num-=9;
 
      }
 
      EndTime = GetTickCount();
      long int times = EndTime - StartTime;
 
      return times;
 
}
вот результат в милисекундах:
0
Миниатюры
Конвертация числа в строку и обратно, условие исключения, разность.  
Напильнег
480 / 118 / 10
Регистрация: 30.09.2010
Сообщений: 473
21.11.2010, 12:30 #26
Цитата Сообщение от norge_goth Посмотреть сообщение
ты наверно перепутал свой быдло-код с моим когда тестил,
Ключевое слово тут "наверно".

Вот это:
C++
1
2
3
4
5
                        if ((d!=a)&&(d!=b)&&(d!=c)) {
                            if (rev_num==(num-k))
                                count++;
                                printf("\n number %d \n", num);
                        }
- не мой быдлокод! Это результат правки моего кода Вашими кривыми ручками.

Правильная правка выглядит так:
C++
1
2
3
4
5
6
                        if ((d!=a)&&(d!=b)&&(d!=c)) {
                            if (rev_num==(num-k)) {
                                count++;
                                printf("k = %d  number = %d\n", k, num);
                            }
                        }
- детский сат, штаны на лямках, на, сопли вам еще подтирать надо.

А вот результат:
0
Миниатюры
Конвертация числа в строку и обратно, условие исключения, разность.  
norge_goth
62 / 62 / 7
Регистрация: 27.01.2009
Сообщений: 279
21.11.2010, 12:53 #27
Цитата Сообщение от Напильнег Посмотреть сообщение
Правильная правка выглядит так:
да признаю с тем я провтыкал, но нет у меня тех заоблачных показателей твоего "супер кода" вот что на самом деле:

да код проигрывает, но напрашивается тогда вопрос зачем вообще тогда писать код понятный человеку если можно использовать асм или вообще машинные кода которые работают быстрее? зачем вообще придумали языки высокого уровня, чтобы на них быдлокодить? или чтобы на осцилографах делать расчет траекторий?
0
Миниатюры
Конвертация числа в строку и обратно, условие исключения, разность.  
Напильнег
480 / 118 / 10
Регистрация: 30.09.2010
Сообщений: 473
21.11.2010, 22:17 #28
Цитата Сообщение от norge_goth Посмотреть сообщение
но нет у меня тех заоблачных показателей твоего "супер кода" вот что на самом деле:
Вообще-то то, что ты видишь "на самом деле", в 36 раз эффективнее твоего. Причина, что показатели другие... Возможно, VS код оптимизирует лучше, или консольный вывод у тебя в системе работает медленнее, тем более, что ты опять в "моем" коде лишний скроллинг экрана делаешь, а это затратная операция. Давай весь исходник, посмотрим, че там.

Цитата Сообщение от norge_goth Посмотреть сообщение
да код проигрывает
Он не проигрывает, он ужасен - имея десятичные цифры, преобразовывать их в строковое представление числа, а затем строковое представление преобразовывать в число - это экспонат для кунсткамеры.

Цитата Сообщение от norge_goth Посмотреть сообщение
но напрашивается тогда вопрос зачем вообще тогда писать код понятный человеку если можно использовать асм или вообще машинные кода которые работают быстрее?
Вообще-то, твой код менее понятен человеку, чем код, использующий простые умножения для преобразования набора цифр в число - так то.
0
21.11.2010, 22:17
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.11.2010, 22:17
Привет! Вот еще темы с ответами:

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

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

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

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


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

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

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