#Language: T-SQL
#Style: Big Numbers
Вот еще одно решение T-SQL - поддержка больших чисел в рубиново-голдберговой манере. Много основанных на множестве операций. Пытался сохранить это однозначно SQL. Ужасная производительность (400! Потребовалось 33 секунды на Dell Latitude D830)
create function bigfact(@x varchar(max)) returns varchar(max) as begin
declare @c int
declare @n table(n int,e int)
declare @f table(n int,e int)
set @c=0
while @c<len(@x) begin
set @c=@c+1
insert @n(n,e) values(convert(int,substring(@x,@c,1)),len(@x)-@c)
end
-- our current factorial
insert @f(n,e) select 1,0
while 1=1 begin
declare @p table(n int,e int)
delete @p
-- product
insert @p(n,e) select sum(f.n*n.n), f.e+n.e from @f f cross join @n n group by f.e+n.e
-- normalize
while 1=1 begin
delete @f
insert @f(n,e) select sum(n),e from (
select (n % 10) as n,e from @p union all
select (n/10) % 10,e+1 from @p union all
select (n/100) %10,e+2 from @p union all
select (n/1000)%10,e+3 from @p union all
select (n/10000) % 10,e+4 from @p union all
select (n/100000)% 10,e+5 from @p union all
select (n/1000000)%10,e+6 from @p union all
select (n/10000000) % 10,e+7 from @p union all
select (n/100000000)% 10,e+8 from @p union all
select (n/1000000000)%10,e+9 from @p
) f group by e having sum(n)>0
set @c=0
select @c=count(*) from @f where n>9
if @c=0 break
delete @p
insert @p(n,e) select n,e from @f
end
-- decrement
update @n set n=n-1 where e=0
-- normalize
while 1=1 begin
declare @e table(e int)
delete @e
insert @e(e) select e from @n where n<0
if @@rowcount=0 break
update @n set n=n+10 where e in (select e from @e)
update @n set n=n-1 where e in (select e+1 from @e)
end
set @c=0
select @c=count(*) from @n where n>0
if @c=0 break
end
select @c=max(e) from @f
set @x=''
declare @l varchar(max)
while @c>=0 begin
set @l='0'
select @l=convert(varchar(max),n) from @f where e=@c
set @x=@x+@l
set @c=@c-1
end
return @x
end
Пример:
print dbo.bigfact('69')
возвращает:
171122452428141311372468338881272839092270544893520369393648040923257279754140647424000000000000000
Попробуйте
cout << "Enter name:";
cin.ignore();
getline(cin, str);
getline (cin, str);
считывает новую строку, которая идет после числа, прочитанного ранее, и немедленно возвращается с этой «строкой». Чтобы избежать этого, вы можете пропустить пробелы с помощью std :: ws
перед чтением имени:
cout << "Enter number:";
cin >> number;
cout << "Enter name:";
ws(cin);
getline(cin, str);
...
Обратите внимание, что это также пропускает ведущие пробелы после новой строки, поэтому str
не будет начинаться с пробелов , даже если пользователь их ввел. Но в данном случае это, вероятно, функция, а не ошибка ...
std :: ws
перед чтением имени:
cout << "Enter number:";
cin >> number;
cout << "Enter name:";
ws(cin);
getline(cin, str);
...
Обратите внимание, что это также пропускает ведущие пробелы после новой строки, поэтому str
не будет начинаться с пробелов , даже если пользователь их ввел. Но в данном случае это, вероятно, функция, а не ошибка ...
std :: ws
перед чтением имени:
cout << "Enter number:";
cin >> number;
cout << "Enter name:";
ws(cin);
getline(cin, str);
...
Обратите внимание, что это также пропускает ведущие пробелы после новой строки, поэтому str
не будет начинаться с пробелов , даже если пользователь их ввел. Но в данном случае это, вероятно, функция, а не ошибка ...
cin >> number // eat the numeric characters
getline(cin, str) // eat the remaining newline
cin >> number
только берет числа из буфера, он оставляет "войти" в буфер,
Похоже, вам нужно чтение по строкам. Для этого вы, вероятно, захотите последовательно использовать getline
, а затем анализировать каждую строку, если вам нужно проанализировать число из прочитанной строки. Это делает входное чтение более согласованным.
Таким образом, вам не нужно вручную сканировать конец каждой строки, чтобы гарантировать, что следующая операция чтения начинается с новой строки.
Это также позволяет добавить обработку ошибок для проще повторять запросы ввода.
например,
#include <string>
#include <iostream>
#include <istream>
#include <ostream>
#include <sstream>
int parse_integer(const std::string& input)
{
std::istringstream iss(input);
int result;
if (!(iss >> result))
{
// error - throw something?
}
return result;
}
int main()
{
int number;
std::string str;
int accountNumber;
std::string inputline;
std::cout << "Enter number: ";
if (!std::getline(std::cin, inputline))
{
// error - throw something?
}
number = parse_integer(inputline);
std::cout << "Enter name:";
if (!std::getline(std::cin, inputline))
{
// error - throw something?
}
str = inputline;
std::cout << "Enter account number:";
if (!std::getline(std::cin, inputline))
{
// error - throw something?
}
accountNumber = parse_integer(inputline);
return 0;
}
Я думаю, проблема в том, что cin >>
передает символ новой строки (\ n)
. Getline () предполагает, что символ новой строки является пробелом, и передает его. Кто-то опубликовал решение, которое вы можете использовать.
Вы можете использовать фиктивный getline (cin, dummy);
или настоящий cin. ignore (100, '\ n');