如何只用C语言做这个题目?
有一个喜欢装逼的学长,英语词汇量没到20个词还不会语法,却总想着拽两句英文,问个a+b都不会好好问,非用英文问。这位学长特有的语法是,按位直接说英文,例如123他会念成one two three,123+456他会念one two three add four five six,结果是five seven nine
而1+2他会念one add two,结果是three
这位学长为了照顾英文不好的同学,他教大家学英语
0 zero
1 one
2 two
3 three
4 four
5 five
6 six
7 seven
8 eight
9 nine
输入
输入由1行字符串组成,形如题面描述(保证0<=a,b < 1000)
输出
按题面描述形式输出a+b的结果
样例输入
one two three add four five six
one add two
zero add one
样例输出
five seven nine
three
one
提示
能多组输入
原题网址:http://120.78.162.102/problem.php?cid=1412&pid=3 必须是C语言?
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
static const std::vector<std::string>g_table = {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"};
static size_t WordToNumber(const std::string &word)
{
for(auto iter = g_table.begin(); iter != g_table.end(); ++iter)
{
if(*iter == word)
return iter - g_table.begin();
}
return -1;
}
static const std::string NumberToString(size_t number)
{
std::stringstream ss;
ss << number;
char ch;
std::string result;
std::string separator;
while(ss >> ch)
{
result += separator + g_table;
separator = " ";
}
return result;
}
const std::string GetResult(const std::string &expression)
{
std::stringstream ss;
ss << expression;
size_t a = 0, b = 0;
std::string word;
while(ss >> word && word != "add")
{
a = a * 10 + WordToNumber(word);
}
while(ss >> word)
{
b = b * 10 + WordToNumber(word);
}
return NumberToString(a + b);
}
int main()
{
std::vector<std::string> expression;
std::string line;
while(std::getline(std::cin, line))
expression.push_back(line);
for(auto const &i: expression)
std::cout << GetResult(i) << std::endl;
return 0;
}
one two three add four five six
one add two
zero add one
^Z
five seven nine
three
one
请按任意键继续. . .
人造人 发表于 2018-12-9 14:16
必须是C语言?
是的……我那大妹子被要求必须用C语言…………
欸老哥,我临时这边有个问题想不通。。。
就是不明白,为什么IEEE 754标准里的 阶码的偏移量是127。。。我看计算机组成原理的时候,前面说的是 移码=补码的符号位取反 或者用真值+2^n次方 来表示
为什么一到IEEE 754这里就变成了真值+2^n次方-1 这个-1是哪里来的??
还有就是
隐含位的问题,这是IEEE754规定的是吧,是为了让尾数的精度能提高一些吗?
我百度了很多,但是没有看到什么特别好的回答QAQ
求大佬帮帮孩子吧 彭尼玛 发表于 2018-12-9 17:47
是的……我那大妹子被要求必须用C语言…………
欸老哥,我临时这边有个问题想不通。。。
就是不明白, ...
#include <stdio.h>
#include <string.h>
static const char *g_table[] = {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"};
static const size_t g_table_size = sizeof(g_table) / sizeof(g_table);
static size_t WordToNumber(const char *word)
{
for(size_t i = 0; i < g_table_size; ++i)
{
if(!strcmp(word, g_table))
return i;
}
return -1;
}
static const char *NumberToString(char *dest, size_t number)
{
char buf;
sprintf(buf, "%d", number);
char *separator = "";
dest = '\0';
for(size_t i = 0; buf; ++i)
{
strcat(dest, separator);
strcat(dest, g_table - '0']);
separator = " ";
}
return dest;
}
size_t GetWord(char *dest, const char *string)
{
size_t count = 0;
while(string && string != ' ')
++count;
strncpy(dest, string, count);
dest = '\0';
return count;
}
const char *GetResult(char *dest, const char *expression)
{
size_t a = 0, b = 0;
char word;
size_t offset = 0;
size_t size;
while((size = GetWord(word, expression + offset)) && (offset += size + 1) && strcmp(word, "add"))
{
a = a * 10 + WordToNumber(word);
}
while((size = GetWord(word, expression + offset)) && (offset += size + 1))
{
b = b * 10 + WordToNumber(word);
}
return NumberToString(dest, a + b);
}
int main()
{
char expression;
size_t size = 0;
while(fgets(expression, 512, stdin))
{
expression) - 1] = '\0'; // 去掉'\n'
++size;
}
char dest;
for(size_t i = 0; i < size; ++i)
{
puts(GetResult(dest, expression));
}
return 0;
}
彭尼玛 发表于 2018-12-9 17:47
是的……我那大妹子被要求必须用C语言…………
欸老哥,我临时这边有个问题想不通。。。
就是不明白, ...
浮点数部分我需要研究研究
人造人 发表于 2018-12-9 22:41
感动,谢谢,替我大妹子感谢你QAQ 彭尼玛 发表于 2018-12-9 17:47
是的……我那大妹子被要求必须用C语言…………
欸老哥,我临时这边有个问题想不通。。。
就是不明白, ...
目前我已经研究了差不多一半了,我还需要一些时间研究另外差不多一半的内容
人造人 发表于 2018-12-15 15:03
目前我已经研究了差不多一半了,我还需要一些时间研究另外差不多一半的内容
{:5_99:}计算机组成原理,好多看得不是很懂的,现在开始学数据结构和算法QAQ 彭尼玛 发表于 2018-12-16 11:04
计算机组成原理,好多看得不是很懂的,现在开始学数据结构和算法QAQ
C语言学完了是吧?
建议先学汇编语言
有了C语言和汇编语言之后,你就可以任意选择了
如果愿意,再加上C++
^_^
人造人 发表于 2018-12-16 12:41
C语言学完了是吧?
建议先学汇编语言
有了C语言和汇编语言之后,你就可以任意选择了
看完了C和C++ ,汇编准备先学完数据结构在那个 彭尼玛 发表于 2018-12-9 17:47
是的……我那大妹子被要求必须用C语言…………
欸老哥,我临时这边有个问题想不通。。。
就是不明白, ...
两个星期了,我已经失去耐心了,估计下面这两个程序再也不会被完善了,最多就是重写这两个程序了^_^
这两个程序的设计上面的问题限制了继续对其完善,也许还有办法,但是我选择放弃这两个程序
解析单精度浮点数的存储格式
#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>
#define BOOST_CONFIG_SUPPRESS_OUTDATED_MESSAGE
#include <boost/multiprecision/cpp_int.hpp>
static const std::string NumberToDecimalString(uint64_t num)
{
std::stringstream ss;
ss << std::setprecision(0) << std::fixed << num;
return ss.str();
}
static size_t DecimalStringToNumber(const std::string &string)
{
std::stringstream ss;
ss << string;
size_t result;
ss >> result;
return result;
}
static const std::string NumberToBinaryString(uint32_t num)
{
std::string result;
for(uint32_t mask = 0x80000000; mask; mask >>= 1)
{
if(mask & num)
result += "1";
else
result += "0";
}
return result;
}
static size_t BinaryStringToNumber(std::string string)
{
size_t result = 0;
size_t size = string.size();
for(auto iter = string.begin(); iter != string.end(); ++iter)
{
if(*iter == '1')
{
size_t index = size - (iter - string.begin()) - 1;
result += size_t(pow(2, index));
}
}
return result;
}
static const std::string GetIntegerPart(const std::string binary_string)
{
return NumberToDecimalString(BinaryStringToNumber(binary_string));
}
static const std::string GetDecimalPart(const std::string binary_string)
{
using bigint = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<>>;
bigint value = 1; // 随便一个数字,这里使用数字1;为了最后的字符串前面有0,例如0625
for(auto iter = binary_string.begin(); iter != binary_string.end(); ++iter)
{
value *= 10;
if(*iter == '1')
{
int index = iter - binary_string.begin();
value += uint64_t(pow(2, -(index + 1)) * pow(10, index + 1));
}
}
std::string num = value.str();
num.erase(num.begin()); // 去掉上面的那个'1'
while(!num.empty() && (*(num.end() - 1) == '0')) // 删除末尾的'0'
num.erase(num.end() - 1);
if(num == "") // 不能全删掉
num = "00";
return num;
}
const std::string ParseFloat(float num)
{
std::string binary_string = NumberToBinaryString(*(uint32_t *)&num);
char sign = binary_string;
std::string exponent = std::string(binary_string.begin() + 1, binary_string.begin() + 9);
std::string fraction = std::string(binary_string.begin() + 9, binary_string.end());
int32_t e = BinaryStringToNumber(exponent);
if(e == 0xFF) // INF or NaN
{
if(BinaryStringToNumber(fraction))
return "NaN";
return "INF";
}
if(e == 0) // 非正规化
{
fraction.insert(fraction.begin(), '0');
}
else
{
fraction.insert(fraction.begin(), '1');
e -= 127;
}
size_t pos;
if(e >= 0)
{
pos = e + 1;
}
else
{
while(e++ < 0)
fraction.insert(fraction.begin(), '0');
pos = 1;
}
return GetIntegerPart(std::string(fraction.begin(), fraction.begin() + pos))
+ "." + GetDecimalPart(std::string(fraction.begin() + pos, fraction.end()));
}
int main()
{
float num;
num = 3.1415926F;
std::cout << "0x" << std::hex << std::uppercase << *(uint32_t *)&num << ": " << ParseFloat(num) << std::endl;
num = 0.0F;
std::cout << "0x" << std::hex << std::uppercase << *(uint32_t *)&num << ": " << ParseFloat(num) << std::endl;
num = 0.005F;
std::cout << "0x" << std::hex << std::uppercase << *(uint32_t *)&num << ": " << ParseFloat(num) << std::endl;
num = 1234;
std::cout << "0x" << std::hex << std::uppercase << *(uint32_t *)&num << ": " << ParseFloat(num) << std::endl;
return 0;
}
构造单精度浮点数的存储格式,这个代码还有问题,我知道为什么,但是却没办法修改它,这个代码太乱了,我实在是不想继续在其上面完善了
#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>
#include <cmath>
#define BOOST_CONFIG_SUPPRESS_OUTDATED_MESSAGE
#include <boost/multiprecision/cpp_int.hpp>
using BigInteger = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<>>;
static const std::string IntegerPartToBinaryString(const std::string &string, size_t bits)
{
BigInteger num(string);
std::string result;
while(num)
{
if(num % 2)
result += "1";
else
result += "0";
num /= 2;
}
std::reverse(result.begin(), result.end());
if(bits)
{
while(result.size() != bits)
result.insert(result.begin(), '0');
}
if(result.size() == 0)
result += "0";
return result;
}
static const std::string RemovePrefixZero(const std::string &string)
{
auto iter = string.begin();
for(; iter != string.end(); ++iter)
{
if(*iter != '0')
break;
}
if(iter == string.end())
return std::string("0");
return std::string(iter, string.end());
}
static void BinaryCarry(std::string &string)
{
for(auto iter = string.rbegin(); iter != string.rend(); ++iter)
{
if(*iter == '0')
{
*iter = '1';
break;
}
*iter = '0';
}
}
static const std::string DecimalPartToBinaryString(const std::string &string, size_t bits)
{
BigInteger num = BigInteger(pow(10, string.size()));
num += BigInteger(RemovePrefixZero(string));
std::string result;
for(size_t i = 0; i < bits + 1; ++i)
{
num *= 2;
num -= BigInteger(pow(10, string.size()));
BigInteger remainder = (num / BigInteger(pow(10, string.size()))) % 10;
if(remainder > 1)
{
num -= BigInteger(pow(10, string.size()));
result += "1";
}
else
{
result += "0";
}
}
char ch = *(result.end() - 1);
result.erase(result.end() - 1);
if(ch == '1')
{
BinaryCarry(result);
}
return result;
}
static const std::string GetFraction(const std::string &binary_integer_part, const std::string &binary_decimal_part)
{
std::string fraction = binary_integer_part + binary_decimal_part;
fraction.erase(fraction.begin());
return fraction;
}
static const std::string GetExponent(size_t exponent, bool normalization)
{
if(!normalization)
return std::string("00000000");
BigInteger num = exponent + 127;
return IntegerPartToBinaryString(num.str(), 8);
}
static void SetBit(uint32_t &data, bool bit, size_t pos)
{
data &= ~(1 << pos);
data |= bit << pos;
}
static uint32_t MakeFloat(bool sign, const std::string &exponent, const std::string &fraction)
{
uint32_t num = 0;
SetBit(num, sign, 31);
for(int i = 30; i != 22; --i)
SetBit(num, exponent == '1', i);
for(int i = 22; i >= 0; --i)
SetBit(num, fraction == '1', i);
return num;
}
size_t ParseFloat(std::string num)
{
std::string integer_part;
std::string decimal_part;
size_t pos = num.find('.');
if(pos == std::string::npos)
{
integer_part = num;
decimal_part = "0";
}
else
{
integer_part = std::string(num.begin(), num.begin() + pos);
decimal_part = std::string(num.begin() + pos + 1, num.end());
}
std::string binary_integer_part = IntegerPartToBinaryString(integer_part, 0);
std::string binary_decimal_part = DecimalPartToBinaryString(decimal_part, 23 - (binary_integer_part.size() - 1));
std::string exponent;
if(binary_integer_part == "0")
exponent = GetExponent(binary_integer_part.size() - 1, false); // 非正规化
else
exponent = GetExponent(binary_integer_part.size() - 1, true); // 正规化
std::string fraction = GetFraction(binary_integer_part, binary_decimal_part);
return MakeFloat(num == '-', exponent, fraction);
}
int main()
{
float num;
std::cout << std::hex << std::uppercase;
num = 3.14F;
std::cout << *(uint32_t *)&num << " -> " << ParseFloat("3.14") << std::endl;
num = 1234.0F;
std::cout << *(uint32_t *)&num << " -> " << ParseFloat("1234") << std::endl;
num = 3.1415926F;
std::cout << *(uint32_t *)&num << " -> " << ParseFloat("3.1415926") << std::endl;
num = 0.0F;
std::cout << *(uint32_t *)&num << " -> " << ParseFloat("0") << std::endl;
num = 0.005F;
std::cout << *(uint32_t *)&num << " -> " << ParseFloat("0.005") << std::endl;
return 0;
}
本帖最后由 人造人 于 2018-12-22 13:35 编辑
https://www.jianshu.com/p/e5d72d764f2f
为什么一到IEEE 754这里就变成了真值+2^n次方-1 这个-1是哪里来的??
因为要把 0000 0000 和 1111 1111 留出来给 “非正规化”
加127正好把这个数(正数)向上偏移了 “一半”,如果是负数,那就向下偏移
从中间向两边偏移,把两个极限值 0000 0000 和 1111 1111 留出来用于“非正规化”表示
更正:0000 0000用于“非正规化”,1111 1111用于Inf和NaN
隐含位的问题,这是IEEE754规定的是吧,是为了让尾数的精度能提高一些吗?
可以这么说,因为这个隐含位要么恒为1,要么恒为0,没有必要存储这一位,至于是恒为1,还是恒为0,取决于是“正规化”还是“非正规化”
差点忘了这个
这个是写上面那两个程序时的中间数据,也许有参考价值
0.14 * 2 = 0.28 0
0.28 * 2 = 0.56 0
0.56 * 2 = 1.12 1
0.12 * 2 = 0.24 0
0.24 * 2 = 0.48 0
0.48 * 2 = 0.96 0
0.96 * 2 = 1.92 1
0.92 * 2 = 1.84 1
0.84 * 2 = 1.68 1
0.68 * 2 = 1.36 1
0.36 * 2 = 0.72 0
0.72 * 2 = 1.44 1
0.44 * 2 = 0.88 0
0.88 * 2 = 1.76 1
0.76 * 2 = 1.52 1
0.52 * 2 = 1.04 1
0.04 * 2 = 0.08 0
0.08 * 2 = 0.16 0
0.16 * 2 = 0.32 0
#include <stdio.h>
int main()
{
double num = 0.14;
for(size_t i = 0; i < 32; ++i)
{
printf("%.4f * 2 = %.4f\t%d\n", num, num * 2, (num * 2 > 1) ? 1 : 0);
num *= 2;
if(num > 1)
num -= 1;
}
return 0;
}
0.1400 * 2 = 0.2800 0
0.2800 * 2 = 0.5600 0
0.5600 * 2 = 1.1200 1
0.1200 * 2 = 0.2400 0
0.2400 * 2 = 0.4800 0
0.4800 * 2 = 0.9600 0
0.9600 * 2 = 1.9200 1
0.9200 * 2 = 1.8400 1
0.8400 * 2 = 1.6800 1
0.6800 * 2 = 1.3600 1
0.3600 * 2 = 0.7200 0
0.7200 * 2 = 1.4400 1
0.4400 * 2 = 0.8800 0
0.8800 * 2 = 1.7600 1
0.7600 * 2 = 1.5200 1
0.5200 * 2 = 1.0400 1
0.0400 * 2 = 0.0800 0
0.0800 * 2 = 0.1600 0
0.1600 * 2 = 0.3200 0
0.3200 * 2 = 0.6400 0
0.6400 * 2 = 1.2800 1
0.2800 * 2 = 0.5600 0
0.5600 * 2 = 1.1200 1
0.1200 * 2 = 0.2400 0
0.2400 * 2 = 0.4800 0
0.4800 * 2 = 0.9600 0
0.9600 * 2 = 1.9200 1
0.9200 * 2 = 1.8400 1
0.8400 * 2 = 1.6800 1
0.6800 * 2 = 1.3600 1
0.3600 * 2 = 0.7200 0
0.7200 * 2 = 1.4400 1
请按任意键继续. . .
1 0 -1-2-3-4-5-6-7-8-9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22
1 1. 0 0 1 0 0 0 1 1 1 1 0 1 0 1 1 1 0 0 0 0 1 1
2^-3 + 2^-7 + 2^-8 + 2^-9 + 2^-10 + 2^-12 + 2^-14 + 2^-15 + 2^-16 + 2^-21 + 2^-22
2^-1 = 0.5
2^-2 = 0.25
2^-3 = 0.125
2^-4 = 0.0625
2^-5 = 0.03125
2^-6 = 0.015625
#include <stdio.h>
#include <math.h>
int main()
{
char format;
for(int i = 1; i <= 32; ++i)
{
sprintf(format, "2^-%d = %%.%dlf\n", i, i);
printf(format, pow(2, -i));
}
return 0;
}
123456789 10 11 12 13 14 15 16 17 18 19 20 21 22
0010001111010111000011
2^-1 = 0.5
2^-2 = 0.25
2^-3 = 0.125
2^-4 = 0.0625
2^-5 = 0.03125
2^-6 = 0.015625
2^-7 = 0.0078125
2^-8 = 0.00390625
2^-9 = 0.001953125
2^-10 = 0.0009765625
2^-11 = 0.00048828125
2^-12 = 0.000244140625
2^-13 = 0.0001220703125
2^-14 = 0.00006103515625
2^-15 = 0.000030517578125
2^-16 = 0.0000152587890625
2^-17 = 0.00000762939453125
2^-18 = 0.000003814697265625
2^-19 = 0.0000019073486328125
2^-20 = 0.00000095367431640625
2^-21 = 0.000000476837158203125
2^-22 = 0.0000002384185791015625
2^-23 = 0.00000011920928955078125
2^-24 = 0.000000059604644775390625
2^-25 = 0.0000000298023223876953125
2^-26 = 0.00000001490116119384765625
2^-27 = 0.000000007450580596923828125
2^-28 = 0.0000000037252902984619140625
2^-29 = 0.00000000186264514923095703125
2^-30 = 0.000000000931322574615478515625
2^-31 = 0.0000000004656612873077392578125
2^-32 = 0.00000000023283064365386962890625
请按任意键继续. . .
0.0000000101000111101011100001010
*************************************************************
0.005
005
1005
人造人 发表于 2018-12-22 12:47
https://www.jianshu.com/p/e5d72d764f2f
为什么一到IEEE 754这里就变成了真值+2^n次方-1 这个-1是哪 ...
谢谢,超感动QAQ,没想到仁兄还记得这个QAQ,哇,最近比较少登入鱼C,一上来就好感动,QAQ 彭尼玛 发表于 2018-12-28 11:05
谢谢,超感动QAQ,没想到仁兄还记得这个QAQ,哇,最近比较少登入鱼C,一上来就好感动,QAQ
当然记得
^_^ 刚入门中
页:
[1]