C/C++每日一练(20230317)

简介: C/C++每日一练(20230317)

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:

4a18acda10c1606aa5d1132b9de26d61.png


输入:head = [3,2,0,-4], pos = 1

输出:返回索引为 1 的链表节点

解释:链表中有一个环,其尾部连接到第二个节点。


示例 2:


1a6fcfc68d7340c39151075f7fa53150.png



输入:head = [1,2], pos = 0

输出:返回索引为 0 的链表节点

解释:链表中有一个环,其尾部连接到第一个节点。


示例 3:


3039274e08a9385ea77b20a81060ed40.png



输入: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)



目录
相关文章
|
Linux 监控 Ubuntu
Linux 终端操作命令(1)
Linux 终端操作命令(1)
231 1
Linux 终端操作命令(1)
|
算法 Java Go
Rust每日一练(Leetday0018) N皇后II、最大子数组和、螺旋矩阵
Rust每日一练(Leetday0018) N皇后II、最大子数组和、螺旋矩阵
206 1
Rust每日一练(Leetday0018) N皇后II、最大子数组和、螺旋矩阵
|
Linux 监控 Shell
Linux 终端命令之文件浏览(4) head, tail
Linux 终端命令之文件浏览(4) head, tail
200 0
Linux 终端命令之文件浏览(4) head, tail
|
Shell Linux 机器学习/深度学习
Linux 终端操作命令(3)内部命令用法
Linux 终端操作命令(3)内部命令用法
227 0
Linux 终端操作命令(3)内部命令用法
|
Python Linux Ubuntu
Linux系统部署Python语言开发运行环境
Linux系统部署Python语言开发运行环境
522 0
Linux系统部署Python语言开发运行环境
|
Go Unix 开发者
Go语言time库,时间和日期相关的操作方法
Go语言time库,时间和日期相关的操作方法
391 0
Go语言time库,时间和日期相关的操作方法
|
C++ 存储 Serverless
力扣C++|一题多解之数学题专场(2)
力扣C++|一题多解之数学题专场(2)
220 0
力扣C++|一题多解之数学题专场(2)
|
Go 机器学习/深度学习 Rust
Golang每日一练(leetDay0119) 反转字符串I\II Reverse String
Golang每日一练(leetDay0119) 反转字符串I\II Reverse String
318 0
Golang每日一练(leetDay0119) 反转字符串I\II Reverse String
|
Java Go C++
Golang每日一练(leetDay0115) 重新安排行程、递增的三元子序列
Golang每日一练(leetDay0115) 重新安排行程、递增的三元子序列
150 0
Golang每日一练(leetDay0115) 重新安排行程、递增的三元子序列
|
Java Go C++
Golang每日一练(leetDay0111) 摆动排序II\I Wiggle Sort
Golang每日一练(leetDay0111) 摆动排序II\I Wiggle Sort
192 0
Golang每日一练(leetDay0111) 摆动排序II\I Wiggle Sort