Возникли проблемы с практическим заданием: Удалите все цифры, которые можно найти слева от самой правой цифры 1
Я начал изучать C++ в университете. Сейчас изучаем циклы. Задача: Ввод: целое число (integer number). Удалите все цифры, которые можно найти слева от самой правой цифры 1.
Пример:
- Ввод: 314195
- Результат: 95
Или:
- Ввод: 45131005
- Результат: 005
Для этой задачи мы не можем использовать массивы или команды типа string. Однако мы можем использовать математические функции. Также обязательно должно быть условие while/do while.
Я написал код, который находит значения до первой цифры 1, используя % и /. Однако в результате он не работает должным образом, и когда я ввожу что-то вроде 431004, выводится только 4, а не 004. Есть идея сделать иначе: выписывать результат каждого действия (остаток деления) в самом цикле. Но в таком случае цифры будут в обратном порядке (т.е. например, имея 431004, получим 400, а не 004.
Вот мой уже написанный код:
#include <iostream>
using namespace std;
int main()
{
int number;
cout << endl << "Enter integer number: ";
cin >> number;
int result;
int buffer = 0;
int divider = 10;
int check = 1;
do {
result = buffer;
buffer = number % divider;
divider = divider * 10;
check *= 10;
} while ((buffer / (check / 10)) != 1);
cout << endl << "Result = " << result;
return 0;
}
Ответы (2 шт):
Если нужно печатать строки вроде 005, хранить результат в виде числа - плохая идея. С другой стороны можно печатать цифры исходного числа, если знать место с которого начать:
#include <iostream>
int main() {
int n;
std::cin >> n;
// ищем p - степень десятки с которой будем печатать хвост числа
int p;
for (p = 1; ; p *= 10) {
if ((n / p) % 10 == 1) {
// p указывает на единицу, отступаем на шаг назад и выходим
p /= 10;
break;
}
// проверку можно было бы сделать в заголовке цикла,
// но так нет переполнения при работе с большими числами
if (p > n / 10) {
// следующий p превысит n, пора закругляться
break;
}
}
// печатаем цифры от старших к младшим
// специально сделал через while, хотя for тут удобнее
while (p > 0) {
std::cout << (n / p) % 10;
p /= 10;
}
std::cout << '\n';
}
$ g++ -std=c++17 -pedantic -Wall -Wextra -Werror -Wwrite-strings -Wconversion temp.cpp $ echo 431004 | ./a.out 004 $ echo 314195 | ./a.out 95 $ echo 2147483647 | ./a.out 47483647 $ echo 2047483647 | ./a.out 2047483647
P.S. Думаете, что, запретив строки и массивы, можно принудить работать с числами? Ничего подобного. Вот решение со списком символов на стеке. Обрабатываются числа (строки цифр) любого размера, лишь бы стек не переполнился.
#include <iostream>
struct node_t {
char digit;
const node_t *prev;
};
void print(const node_t *node) {
if (node != nullptr) {
print(node->prev);
std::cout << node->digit;
}
}
void print_tail(const node_t *prev) {
char c;
std::cin.get(c);
if ('0' <= c && c <= '9') {
if (c == '1') {
print_tail(nullptr);
} else {
node_t node = { c, prev };
print_tail(&node);
}
} else {
print(prev);
std::cout << '\n';
}
}
int main() {
print_tail(nullptr);
}
P.P.S. В предыдущем примере нет цикла while. Хочется встроить его в процедуру печати, да список хранит цифры задом наперёд. Поменяем порядок цифр в списке при его создании. Для этого надо будет передавать список в виде двух указателей - на голову и на хвост. В C++ это удобно делать с помощью ссылок на указатели.
#include <iostream>
struct node_t {
char digit;
node_t *next;
};
void print_tail(node_t *&head, node_t *&tail) {
char c;
std::cin.get(c);
if ('0' <= c && c <= '9') {
if (c == '1') {
node_t *head = nullptr;
print_tail(head, head);
} else {
node_t node = { c, nullptr };
tail = &node;
print_tail(head, node.next);
}
} else {
node_t *p = head;
while (p != nullptr) {
std::cout << p->digit;
p = p->next;
}
std::cout << '\n';
}
}
int main() {
node_t *head = nullptr;
print_tail(head, head);
}
берите разницу между этим числом и таким же числом, но с заменой на нули после последней единицы:
int result = number, n = 1;
while (result && result % 10 != 1)
{
result /= 10;
n *= 10;
}
result = number - result * n;