1044. 火星数字(20)--再次使用到sscanf

本文介绍了一个程序设计案例,实现地球数字与火星文(13进制)之间的相互转换。通过分析输入字符串,利用特定规则将地球数字转换为火星文或反之。文章提供了完整的C++代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述:
火星人是以13进制计数的:

地球人的0被火星人称为tret。
地球人数字1到12的火星文分别为:jan, feb, mar, apr, may, jun, jly, aug, sep, oct, nov, dec。
火星人将进位以后的12个高位数字分别称为:tam, hel, maa, huh, tou, kes, hei, elo, syy, lok, mer, jou。
例如地球人的数字“29”翻译成火星文就是“hel mar”;而火星文“elo nov”对应地球数字“115”。为了方便交流,请你编写程序实现地球和火星数字之间的互译。

输入格式:

输入第一行给出一个正整数N(<100),随后N行,每行给出一个[0, 169)区间内的数字 —— 或者是地球文,或者是火星文。

输出格式:

对应输入的每一行,在一行中输出翻译后的另一种语言的数字。

输入样例:
4
29
5
elo nov
tam
输出样例:
hel mar
may
115
13
题目分析:本题目其实就是进制的转化而已,这个不难。麻烦的是因为不清楚输入的是字符串还是地球数字,因此只能全部按照字符串进行读入。麻烦的是要处理字符串。使用string容器,sscanf()(这个函数的讲解请见这里)能简化工作。
注意点:1.题目要求了数据的范围在[0,169)以内,因此可以看到待转化火星文数字最多只有两位(对于火星数字)。
2.此外注意13 的整数倍,转化成火星文字后不许输出tret。
3.可以根据读入的字符串的第一位是不是在0~9以内来区分地球数字和火星数字

#include<stdio.h>
#include<string>
#include<iostream>
using namespace std;
string huyi1[13]={"tret","jan", "feb", "mar", "apr", "may", "jun", "jly", "aug", "sep", "oct", "nov", "dec"};
string huyi2[13]={"***","tam", "hel", "maa", "huh", "tou", "kes", "hei", "elo", "syy", "lok", "mer", "jou"};
          //这样设置两个数组的好处,是直接可以使用其下标进行计算 
void to_earth(string str){            //实现火星文到地球数字的转化 
    int len=str.length() ;            //首先判断下长度,因为出tret以为都是三个字母,                                       
    if(len<4){                        //所以如果字符串的长度小于4那么可以肯定里面就一位火星文
        for(int i=0;i<13;i++){
            if(str==huyi1[i]){
                 cout<<i<<endl;      //输出对应的地球数字 
            }
            else if(str==huyi2[i]){   //在低位中没找到,就去高位中找 
                cout<<i*13<<endl;
            }
        }
    }
    else{
        int gao,di;      //存放高位数字、低位数字 
        string a=str.substr(0,3) ,b=str.substr(4,3);  //火星文有两位,分别取出来 a为低位,b为高位 
        for(int i=0;i<13;i++){
            if(a==huyi2[i]){  
                gao=i;                //返回高位对应的地球数字 
            }
            if(b==huyi1[i]){
                di=i;                 //返回低位对应的地球数字 
            }
        }
        cout<<gao*13+di<<endl;        //按照格式输出 
    }
}
void to_mars(string str){          //将地球数字转换为火星数字 
    int temp;
    sscanf(str.c_str(),"%d",&temp);   //该函数我之前介绍过了,实现将字符串内容以int型输入到temp当中 
    //sscanf不能对string实行这种操作,使用str的c_str()将其转换成字符数组 
    if(temp<13){
        cout<<huyi1[temp]<<endl;      //数字小于13,属于低位 
    }
    else if(temp%13==0){              //如果是13的倍数,不需输出tret 
        cout<<huyi2[temp/13]<<endl;
    }
    else{
        cout<<huyi2[temp/13]<<" "<<huyi1[temp%13]<<endl;    //按照格式输出高位和低位的火星文 
        }

}
int main()
{
    int n;
    cin>>n;
    string str[1000];
    getchar();
    for(int i=0;i<n;i++){
        getline(cin,str[i]);     //读入每个需要转化的字符串 
    }
    for(int i=0;i<n;i++){
        if(str[i][0]>='0'&&str[i][0]<='9'){   //先检查第一位数字如果是0~9,那么就是地球文字,需要将其转化成火星文字 
            to_mars(str[i]);
        }
        else{
            if(str[i]=="tret"){      //特判,如果字符串就一个tret,直接输出零即可 
                cout<<'0'<<endl;
            }
            else to_earth(str[i]);   //否则进行转换 
        }
    }
    return 0;
}
c语言编程实现【问题描述】 已知微信接龙中每笔订单由序号、客户、订单项组成;每个订单项含品名、数量和单位。接龙的第一行是逗号隔开的所有品名和单位。例如: 苹果 / 份 , 香蕉 / 份 1. 3-2-1101 香蕉 1 份 ; 2. 1-2-1501 苹果 2 份 ; 3. 3-1-2704 香蕉 1 份 , 苹果 1 份 ; 4. 4-2-1904 苹果 2 份 注意,每个词元后面都有空格。建议使用Scanner扫描出词元作为LL(1)分析器的输入,当分析完第1行,创建一个Map<项目,数量>对象;每当当分析一个订单项,就把项目后的数量累加到Map对象中。 参考文法: <微信接龙> -> <项目清单><订单清单> <项目清单> -> <项目>/<单位><其余项目> <其余项目> ->,<项目>/<单位><其余项目>| ε <订单清单> -> <订单><其余订单> <其余订单> ->;<订单><其余订单>| ε <订单> -> <序号>.<标识><订单项清单> <序号> -> 无符号整数 <标识> -> <无符号整数>-<无符号整数>-<无符号整数> <订单项清单> -> <订单项><其余订单项> <其余订单项> ->,<订单项><其余订单项>| ε <订单项> -> <项目><无符号整数><单位> <项目> -> 标识符 <单位> -> 标识符 设计用于语义计算的翻译模式,指能够按照项目汇总。如香蕉共2份;苹果共5份。 【输入形式】 【输出形式】 【样例输入】 苹果 / 份 , 香蕉 / 份 1. 3-2-1101 香蕉 1 份 ; 2. 1-2-1501 苹果 2 份 ; 3. 3-1-2704 香蕉 1 份 , 苹果 1 份 ; 4. 4-2-1904 苹果 2 份 【样例输出】 香蕉 2 苹果 5
最新发布
06-05
### 解析微信接龙订单并汇总各项目数量的C语言实现 要实现一个C语言程序,解析微信接龙格式的订单并统计每个项目的总数量,需要以下步骤。首先,定义输入数据的结构,然后设计解析逻辑,最后输出汇总结果。 #### 输入数据结构 假设微信接龙的格式如下: ``` 1. 张三 2个苹果 3个香蕉 2. 李四 4个苹果 1个香蕉 3. 王五 5个苹果 ``` 程序需要解析上述文本,提取出每个人购买的物品及其数量,并计算每种物品的总数量。 #### 设计解析逻辑 可以使用字符串处理函数(如`strtok`和`sscanf`)来解析输入文本。以下是具体的实现思路: 1. **读取输入文件**:将微信接龙内容存储在一个文本文件中,并通过C语言的文件操作函数读取该文件。 2. **逐行解析**:对每一行进行解析,提取出用户名、物品名称及数量。 3. **数据存储**:使用数组或链表存储解析结果,便于后续汇总。 4. **汇总统计**:遍历存储的数据,按物品名称进行分类汇总。 #### 示例代码 以下是一个完整的C语言实现示例: ```c #include <stdio.h> #include <string.h> #include <stdlib.h> #define MAX_LINES 100 #define MAX_LINE_LEN 256 #define MAX_ITEM_NAME_LEN 50 typedef struct { char name[MAX_ITEM_NAME_LEN]; int count; } Item; typedef struct { char username[50]; Item items[10]; int item_count; } Order; Order orders[MAX_LINES]; int order_count = 0; void parse_line(const char *line) { char username[50], buffer[MAX_LINE_LEN], item_name[MAX_ITEM_NAME_LEN]; int number, idx = 0; // 提取用户名 sscanf(line, "%d. %[^ ]", username); strcpy(orders[order_count].username, username); orders[order_count].item_count = 0; // 剩余部分为物品描述 sscanf(line, "%*d. %*[^ ] %[^\n]", buffer); // 分割物品描述 char *token = strtok(buffer, " "); while (token != NULL) { if (sscanf(token, "%d", &number) == 1) { // 如果是数字 token = strtok(NULL, " "); // 下一个单词为物品名称 if (token != NULL) { strcpy(item_name, token); strcpy(orders[order_count].items[idx].name, item_name); orders[order_count].items[idx].count = number; idx++; orders[order_count].item_count = idx; } } token = strtok(NULL, " "); } order_count++; } void summarize_items() { Item summary[100]; int summary_count = 0; for (int i = 0; i < order_count; i++) { for (int j = 0; j < orders[i].item_count; j++) { int found = 0; for (int k = 0; k < summary_count; k++) { if (strcmp(summary[k].name, orders[i].items[j].name) == 0) { summary[k].count += orders[i].items[j].count; found = 1; break; } } if (!found) { strcpy(summary[summary_count].name, orders[i].items[j].name); summary[summary_count].count = orders[i].items[j].count; summary_count++; } } } printf("汇总结果:\n"); for (int i = 0; i < summary_count; i++) { printf("%s: %d\n", summary[i].name, summary[i].count); } } int main() { char line[MAX_LINE_LEN]; FILE *file = fopen("src/orders.txt", "r"); // 假设接龙内容存储在orders.txt中 if (file == NULL) { printf("无法打开文件\n"); return 1; } while (fgets(line, sizeof(line), file)) { parse_line(line); } fclose(file); summarize_items(); return 0; } ``` #### 说明 1. **文件读取**:程序从`src/orders.txt`文件中读取接龙内容[^1]。 2. **字符串解析**:使用`sscanf`和`strtok`解析每行数据,提取用户名、物品名称及数量。 3. **数据存储**:将解析结果存储在`orders`数组中,便于后续汇总。 4. **汇总逻辑**:通过遍历`orders`数组,按物品名称进行分类汇总,并输出结果。 #### 注意事项 - 输入文件的格式必须严格符合预期,否则可能导致解析错误。 - 程序中的数组大小(如`MAX_LINES`和`MAX_ITEM_NAME_LEN`)应根据实际需求调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值