C/C++每日一练(20230317)
目录
1. 约分 ★
2. 逆波兰表达式求值 ★★
3. 环形链表 II ★★
1. 约分
编写程序,要求用户输入一个分数,然后将其约分为最简式。如:
输入一个分数:8/12
最简分式:2/3
代码:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a, b, x, y, c;
printf("输入一个分式:");
scanf("%d/%d", &a, &b);
if (a < b)
{
x = b;
y = a;
}
else
{
x = a;
y = b;
}
c = x % y;
while (c)
{
x = y;
y = c;
c = x % y;
}
if (b / y != 1)
printf("最简分式为:%d/%d", a / y, b / y);
else
printf("最简分式为:%d", a / y);
return 0;
}
输入输出:
输入一个分式:8/12
最简分式为:2/3
2. 逆波兰表达式求值
根据 逆波兰表示法,求表达式的值。
有效的算符包括 +
、-
、*
、/
。每个运算对象可以是整数,也可以是另一个逆波兰表达式。
说明:
- 整数除法只保留整数部分。
- 给定逆波兰表达式总是有效的。换句话说,表达式总会得出有效数值且不存在除数为 0 的情况。
示例 1:
输入:tokens = ["2","1","+","3","*"] 输出:9 解释:该算式转化为常见的中缀算术表达式为:((2 + 1) * 3) = 9
示例 2:
输入:tokens = ["4","13","5","/","+"] 输出:6 解释:该算式转化为常见的中缀算术表达式为:(4 + (13 / 5)) = 6
示例 3:
输入:tokens = ["10","6","9","3","+","-11","*","/","*","17","+","5","+"] 输出:22 解释: 该算式转化为常见的中缀算术表达式为: ((10 * (6 / ((9 + 3) * -11))) + 17) + 5 = ((10 * (6 / (12 * -11))) + 17) + 5 = ((10 * (6 / -132)) + 17) + 5 = ((10 * 0) + 17) + 5 = (0 + 17) + 5 = 17 + 5 = 22
提示:
1 <= tokens.length <= 10^4
tokens[i]
要么是一个算符("+"
、"-"
、"*"
或"/"
),要么是一个在范围[-200, 200]
内的整数
逆波兰表达式:
逆波兰表达式是一种后缀表达式,所谓后缀就是指算符写在后面。
- 平常使用的算式则是一种中缀表达式,如
( 1 + 2 ) * ( 3 + 4 )
。 - 该算式的逆波兰表达式写法为
( ( 1 2 + ) ( 3 4 + ) * )
。
逆波兰表达式主要有以下两个优点:
- 去掉括号后表达式无歧义,上式即便写成
1 2 + 3 4 + *
也可以依据次序计算出正确结果。 - 适合用栈操作运算:遇到数字则入栈;遇到算符则取出栈顶两个数字进行计算,并将结果压入栈中。
代码:
#include <bits/stdc++.h>
using namespace std;
class Solution
{
public:
int evalRPN(vector<string> &tokens)
{
stack<int> num;
for (int i = 0; i < tokens.size(); ++i)
{
if (tokens[i] == "+" || tokens[i] == "-" || tokens[i] == "*" || tokens[i] == "/")
{
int j;
int a = num.top();
num.pop();
int b = num.top();
num.pop();
if (tokens[i] == "+")
j = b + a;
else if (tokens[i] == "-")
j = b - a;
else if (tokens[i] == "*")
j = b * a;
else
j = b / a;
num.push(j);
}
else
{
num.push(stoi(tokens[i]));
}
}
return num.top();
}
};
int main()
{
Solution s;
vector<string> tokens = {"2","1","+","3","*"};
cout << s.evalRPN(tokens) << endl;
tokens = {"4","13","5","/","+"};
cout << s.evalRPN(tokens) << endl;
tokens = {"10","6","9","3","+","-11","*","/","*","17","+","5","+"};
cout << s.evalRPN(tokens) << endl;
return 0;
}
输出:
9
6
22
3. 环形链表 II
给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null
。
为了表示给定链表中的环,我们使用整数 pos
来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos
是 -1
,则在该链表中没有环。注意,pos
仅仅是用于标识环的情况,并不会作为参数传递到函数中。
说明:不允许修改给定的链表。
进阶:
- 你是否可以使用
O(1)
空间解决此题?
示例 1:
输入:head = [3,2,0,-4], pos = 1 输出:返回索引为 1 的链表节点 解释:链表中有一个环,其尾部连接到第二个节点。
示例 2:
输入:head = [1,2], pos = 0 输出:返回索引为 0 的链表节点 解释:链表中有一个环,其尾部连接到第一个节点。
示例 3:
输入:head = [1], pos = -1 输出:返回 null 解释:链表中没有环。
提示:
- 链表中节点的数目范围在范围
[0, 10^4]
内 -10^5 <= Node.val <= 10^5
pos
的值为-1
或者链表中的一个有效索引
代码:
#include <bits/stdc++.h>
using namespace std;
struct ListNode
{
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
class Solution
{
public:
ListNode *detectCycle(ListNode *head)
{
ListNode *slow, *fast, *p;
slow = fast = p = head;
while (fast && fast->next)
{
slow = slow->next;
fast = fast->next->next;
if (slow == fast)
{
while (p != slow)
{
p = p->next;
slow = slow->next;
}
return p;
}
}
return nullptr;
}
};
ListNode* cycleLinkedList(vector<int>& nums, size_t pos) {
if (nums.empty() || (int)pos == -1) return NULL;
ListNode *head = new ListNode(nums[0]);
ListNode *rear = head;
ListNode *cyclePos = head;
for (size_t i = 1; i < nums.size(); ++i) {
rear->next = new ListNode(nums[i]);
rear = rear->next;
if (i == pos) cyclePos = rear;
}
if (cyclePos) rear->next = cyclePos;
return head;
}
string LList2String(ListNode* head, int nodes = 10) {
ListNode* curNode = head;
int size = 0;
string res = "[";
while (curNode != NULL && size < nodes) {
res += size++ > 0 ? "," : "";
res += to_string(curNode->val);
curNode = curNode->next;
}
return res + "]";
}
int main()
{
Solution s;
vector<int> nums = {3,2,0,-4};
ListNode* head = cycleLinkedList(nums, 1);
cout << LList2String(head) << endl;
ListNode* ring = s.detectCycle(head);
cout << LList2String(ring) << endl;
nums = {1,2,3};
head = cycleLinkedList(nums, 0);
cout << LList2String(head) << endl;
ring = s.detectCycle(head);
cout << LList2String(ring, 12) << endl;
return 0;
}
输出:
[3,2,0,-4,2,0,-4,2,0,-4]
[2,0,-4,2,0,-4,2,0,-4,2]
[1,2,3,1,2,3,1,2,3,1]
[1,2,3,1,2,3,1,2,3,1,2,3]
说明:
创建带环单链表:
ListNode* cycleLinkedList(vector<int>& nums, size_t pos)
遍历带环单链表:
因为遍历无限循环,所以设置默认遍历前10个节点:
string LList2String(ListNode* head, int nodes = 10)
🌟 每日一练刷题专栏 🌟
✨ 持续,努力奋斗做强刷题搬运工!
👍 点赞,你的认可是我坚持的动力!
🌟 收藏,你的青睐是我努力的方向!
✎ 评论,你的意见是我进步的财富!
![]() | Golang每日一练 专栏 |
![]() | Python每日一练 专栏 |
![]() | C/C++每日一练 专栏 |
![]() | Java每日一练 专栏 |
相关文章
- 10min快速回顾C++语法(七)类、结构体、指针链表专题
- 快速排序算法——C/C++
- c++ map和set_STLset和map的区别
- C++构造函数的作用_c++什么是构造函数
- 【c++】【基础】【primer_plus】【第五章】循环语句
- c++ 中map 的find 用法[通俗易懂]
- C++结构体和类的区别_c++有结构体吗
- C/C++语言常用排序算法
- 论c++中的文件操作(竞赛必看)通俗易懂
- C/C++ Qt TabWidget 实现多窗体创建
- C++ 中文周刊 第93期
- C++中的位运算和原码、反码、补码
- C++多线程/原子性操作互斥锁
- c++基础篇之C++ 模板
- 基于C++cin、cin.get()、cin.getline()、getline()、gets()函数的使用详解
- k均值算法c++语言实现代码
- C++内核对象封装单实例启动程序的类
- C++模板类的用法