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

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

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 17, средняя оценка - 4.82
4ance
1 / 1 / 0
Регистрация: 02.11.2010
Сообщений: 78
12.11.2010, 18:07     Конвертация числа в строку и обратно, условие исключения, разность. #1
Здравствуйте! Проблема с задачей:

В четырёхзначном числе все цифры разные и отличны от нуля. если его записать в обратном порядке,
то получится число, на 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? Заранее, спасибо.
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
12.11.2010, 18:07     Конвертация числа в строку и обратно, условие исключения, разность.
Посмотрите здесь:

C++ Конвертация числа в строку
C++ преобразование даты в строку и обратно
C++ решение задачи,конвертация числа в строку.
Конвертация числа в строку (int to char) C++
перевод целого десятичного числа в строку и обратно в десятичное число C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Напильнег
480 / 120 / 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
Итаг, код любителя делать замечания по поводу оформления кода в полной ж..., что в общем-то было предсказуемо, хоть и не до такой степени. Мой код, правда, не дает ожидаемого принципиального выигрыша, но у него есть резерв повышения эффективности, поработаем еще.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
4ance
1 / 1 / 0
Регистрация: 02.11.2010
Сообщений: 78
19.11.2010, 11:04  [ТС]     Конвертация числа в строку и обратно, условие исключения, разность. #22
Почему такая разница в быстродействии?
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
19.11.2010, 11:23     Конвертация числа в строку и обратно, условие исключения, разность. #23
Думаю, у norge_goth код проигрывает за счёт sprintf'ов и sscanf'ов... Если их заменить на стандартные умножения-сложения - всё будет ок.
Напильнег
480 / 120 / 10
Регистрация: 30.09.2010
Сообщений: 473
19.11.2010, 12:19     Конвертация числа в строку и обратно, условие исключения, разность. #24
Цитата Сообщение от silent_1991 Посмотреть сообщение
Если их заменить на стандартные умножения-сложения- всё будет ок.
Что значит если - будет? А count_for_k_Etalon00 что делает?
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;
 
}
вот результат в милисекундах:
Миниатюры
Конвертация числа в строку и обратно, условие исключения, разность.  
Напильнег
480 / 120 / 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);
                            }
                        }
- детский сат, штаны на лямках, на, сопли вам еще подтирать надо.

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

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

Преобразование класса в строку и обратно C++
C++ Конвертация wchar_t в число целого типа. Обработка исключения
Конвертация qint64 в int и обратно C++

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

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

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

Цитата Сообщение от norge_goth Посмотреть сообщение
но напрашивается тогда вопрос зачем вообще тогда писать код понятный человеку если можно использовать асм или вообще машинные кода которые работают быстрее?
Вообще-то, твой код менее понятен человеку, чем код, использующий простые умножения для преобразования набора цифр в число - так то.
Yandex
Объявления
21.11.2010, 22:17     Конвертация числа в строку и обратно, условие исключения, разность.
Ответ Создать тему
Опции темы

Текущее время: 10:00. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru