编程之旅-Day43

目录

Day43-学习内容:

1.剑指Offer

面试题9:用两个栈实现队列

面试题9:用两个队列实现栈

面试题31:栈的压入、弹出序列

 3.华为机试题

例1:简单错误记录

例2:密码验证合格程序 

例3:简单密码


1.剑指Offer

面试题9:用两个栈实现队列

题目描述:用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。

思路:画图

代码:

class Solution
{
public:
    void push(int node) {
        stack1.push(node);
    }

    int pop() {
        if(stack2.size()<=0){
            while(stack1.size()){
                int data=stack1.top();
                stack1.pop();
                stack2.push(data);
            }
        }
        int head=stack2.top();
        stack2.pop();
        return head;
    }

private:
    stack<int> stack1;
    stack<int> stack2;
};

leetcode

class MyQueue {
public:
    /** Initialize your data structure here. */
    MyQueue() {
        
    }
    
    stack<int> stk;
    /** Push element x to the back of queue. */
    void push(int x) {
        stack<int> tmp;
        while(!stk.empty()){
            tmp.push(stk.top());
            stk.pop();
        }
        stk.push(x);
        while(!tmp.empty()){
            stk.push(tmp.top());
            tmp.pop();
        }
    }
    
    /** Removes the element from in front of queue and returns that element. */
    int pop() {
        int data=stk.top();
        stk.pop();
        return data;
    }
    
    /** Get the front element. */
    int peek() {
        return stk.top();
    }
    
    /** Returns whether the queue is empty. */
    bool empty() {
        return stk.empty();   
    }
};

/**
 * Your MyQueue object will be instantiated and called as such:
 * MyQueue* obj = new MyQueue();
 * obj->push(x);
 * int param_2 = obj->pop();
 * int param_3 = obj->peek();
 * bool param_4 = obj->empty();
 */

 

面试题9:用两个队列实现栈

题目描述:

使用队列实现栈的下列操作:

  • push(x) -- 元素 x 入栈
  • pop() -- 移除栈顶元素
  • top() -- 获取栈顶元素
  • empty() -- 返回栈是否为空

注意:

  • 你只能使用队列的基本操作-- 也就是 push to backpeek/pop from frontsize, 和 is empty 这些操作是合法的。
  • 你所使用的语言也许不支持队列。 你可以使用 list 或者 deque(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。
  • 你可以假设所有操作都是有效的(例如, 对一个空的栈不会调用 pop 或者 top 操作)。

代码:

class MyStack {
public:
    /** Initialize your data structure here. */
    MyStack() {
    }
    queue<int> queue1;
    /** Push element x onto stack. */
    void push(int x) {
        queue<int> queue2;
        while(!queue1.empty()){
            queue2.push(queue1.front());
            queue1.pop();
        }
        queue1.push(x);
        while(!queue2.empty()){
            queue1.push(queue2.front());
            queue2.pop();
        }
    }
    
    /** Removes the element on top of the stack and returns that element. */
    int pop() {
        int data=queue1.front();
        queue1.pop();
        return data;
        
    }
    
    /** Get the top element. */
    int top() {
        return queue1.front();
    }
    
    /** Returns whether the stack is empty. */
    bool empty() {
        return queue1.empty();
    }
};

/**
 * Your MyStack object will be instantiated and called as such:
 * MyStack* obj = new MyStack();
 * obj->push(x);
 * int param_2 = obj->pop();
 * int param_3 = obj->top();
 * bool param_4 = obj->empty();
 */

面试题31:栈的压入、弹出序列

题目描述:输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的。

代码:

class Solution {
public:
    bool IsPopOrder(vector<int> pushV,vector<int> popV) {
        bool flag=false;
        if(!pushV.empty()&&!popV.empty()){
            stack<int> stk;
            int lenPush=pushV.size();
            int lenPop=popV.size();
            int i=0;
            int j=0;
            while(i<lenPop){
                while(stk.empty()||stk.top()!=popV[i]){
                    if(j>lenPush){
                        break;
                    }
                    stk.push(pushV[j]);
                    j++;
                }
                if(stk.top()!=popV[i]){
                    break;
                }
                i++;
                stk.pop();
            }
            if(stk.empty()&&i==lenPop){
                flag=true;
            }
        }
        return flag;      
    }
};

 3.华为机试题

例1:简单错误记录

题目描述:

开发一个简单错误记录功能小模块,能够记录出错的代码所在的文件名称和行号。

处理: 

1、 记录最多8条错误记录,循环记录,对相同的错误记录(净文件名称和行号完全匹配)只记录一条,错误计数增加;

2、 超过16个字符的文件名称,只记录文件的最后有效16个字符;

3、 输入的文件可能带路径,记录文件名称不能带路径。

输入描述:

一行或多行字符串。每行包括带路径文件名称,行号,以空格隔开。

输出描述:

将所有的记录统计并将结果输出,格式:文件名 代码行数 数目,一个空格隔开,如:

示例1

输入

E:\V1R2\product\fpgadrive.c   1325

输出

fpgadrive.c 1325 1

思路:结构体

代码:

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <sstream>

using namespace std;

string getFileName(string path){
    int pos = path.rfind('\\');
    return path.substr(pos+1);
}

string modifyName(string filename){
    int len=filename.length();
    if(len>16){
        return filename.substr(len-16);
    }
    return filename;
}

struct ErrRecord{
    string filename;
    int linenum;
    int cnt;
    
    ErrRecord(string filename, int linenum){
        this->filename=filename;
        this->linenum=linenum;
        this->cnt=1;
    }
    
    bool operator == (const ErrRecord & a){
        return (filename==a.filename)&&(linenum==a.linenum);
    }
};   //结构体末尾要加;

int main(){
    string fileName;
    int lineNum;
    vector<ErrRecord> vec;
    while(cin >> fileName >> lineNum){    //输入文件
        ErrRecord record(getFileName(fileName),lineNum);
        auto res=find(vec.begin(),vec.end(),record);
        if(res==vec.end()){
            vec.push_back(record);
        }
        else{
            res->cnt++;
        }    
    }
    
    int count=0;
    for(auto item : vec){   //只输出最后8条,注意用for循环
        if((count+8) >= vec.size()){
            cout << modifyName(item.filename) << " " << item.linenum << " " << item.cnt << endl;
        }
        count++;
    }
    
    return 0;
}

例2:密码验证合格程序 

题目描述:

密码要求:

1.长度超过8位

2.包括大小写字母.数字.其它符号,以上四种至少三种

3.不能有相同长度超2的子串重复

说明:长度超过2的子串

输入描述:

一组或多组长度超过2的子符串。每组占一行

输出描述:

如果符合要求输出:OK,否则输出NG

示例1

输入

021Abc9000
021Abc9Abc1
021ABC9000
021$bc9000

输出

OK NG NG OK

思路:后缀数组比较

时间复杂度O(n*log(n))->sort()

判断字符串中是否有长度超过m的重复子串的方法是后缀数组法 

即统计每个单词的后缀数组,例如对字符串abcdefgabcbc:

a->abcdefgabcbc 

b->bcdefgabcbc

...

a->abcbc

b->bcbc

之后在对这个数组进行排序:

a->abcdefgabcbc

a->abcbc

b->bcdefgabcbc 

b->bcbc 

再对相邻的数组比较前m个字段

代码:

#include <iostream>
#include <string>
#include <algorithm>

using namespace std;
bool cmp(string a,string b){
    return a[0]<b[0];
}

bool JudgeRepeatStr(string str,int m){
    int len=str.length();
    string* suffix=new string[len-m];
    for(int i=0;i<len-m;i++){
        suffix[i]=str.substr(i,len-i);
    }
    sort(suffix,suffix+len-m,cmp);
    for(int i=0;i<len-m-1;i++){
        if(suffix[i].substr(0,m+1)==suffix[i+1].substr(0,m+1)){
            return true;
        }
    }
    return false;
}

int main(){
    string str;
    while(cin>>str){
        int len=str.length();
        if(len<=8){
            cout <<  "NG" << endl;
            continue;
        }
        int mark[4]={0};
        for(int i=0;i<len;i++){
            if(str[i]>='A'&&str[i]<='Z'){
                mark[0]++;
            }
            else if(str[i]>='a'&&str[i]<='z'){
                mark[1]++;
            }
            else if(str[i]>='0'&&str[i]<='9'){
                mark[2]++;
            }
            else{
                mark[3]++;
            }
        }
        
        int typeNum=(mark[0]>0)+(mark[1]>0)+(mark[2]>0)+(mark[3]>0);
        if(typeNum>=3&&JudgeRepeatStr(str,2)==0){
            cout << "OK" << endl;
        }
        else{
            cout << "NG" << endl;
        }
    }
    return 0;
}

例3:简单密码

题目描述:

密码是我们生活中非常重要的东东,我们的那么一点不能说的秘密就全靠它了。哇哈哈. 接下来渊子要在密码之上再加一套密码,虽然简单但也安全。 

假设渊子原来一个BBS上的密码为zvbo9441987,为了方便记忆,他通过一种算法把这个密码变换成YUANzhi1987,这个密码是他的名字和出生年份,怎么忘都忘不了,而且可以明目张胆地放在显眼的地方而不被别人知道真正的密码。 

他是这么变换的,大家都知道手机上的字母: 1--1, abc--2, def--3, ghi--4, jkl--5, mno--6, pqrs--7, tuv--8 wxyz--9, 0--0,就这么简单,渊子把密码中出现的小写字母都变成对应的数字,数字和其他的符号都不做变换, 

声明:密码中没有空格,而密码中出现的大写字母则变成小写之后往后移一位,如:X,先变成小写,再往后移一位,不就是y了嘛,简单吧。记住,z往后移是a哦。

输入描述:

输入包括多个测试数据。输入是一个明文,密码长度不超过100个字符,输入直到文件结尾

输出描述:

输出渊子真正的密文

示例1

输入

YUANzhi1987

输出

zvbo9441987

代码:

#include<iostream>
 
using namespace std;
int table[26] = {2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7,7,7,7,8,8,8,9,9,9,9};
int main(){
    string str;
    while(cin>>str){
        for(int i = 0; i < str.size(); ++i){
            if(str[i] >= 'A' && str[i] < 'Z')
                cout<<(char)(str[i]-'A'+'a'+1);
            else if(str[i] == 'Z')
                cout<<'a';
            else if(str[i] >= 'a' && str[i] <= 'z')
                cout<<table[str[i]-'a'];
            else cout<<str[i];
        }
        cout<<endl;
    }
    return 0;
}

疑问:

用一个新string保存新的结果,无论是+或是push_back,都不能通过!

#include <iostream>
#include <string>

using namespace std;

int table[26]={2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7,7,7,7,8,8,8,9,9,9,9};
int main(){
    string str;
    while(cin>>str){
        string str2="";
        for(int i=0;i<str.length();i++){
            if(str[i]>='A'&&str[i]<'Z'){
                 str2+=char(str[i]-'A'+'a'+1);
            }
            else if(str[i]=='Z'){
                 str2+='a';
            }
            else if(str[i]>='a'&&str[i]<='z'){
                 str2+=table[str[i]-'a'];
            }
            else{
                 str2+=str[i];
            }
        }
        cout << str2 << endl;
    }
    return 0;
}

错误:

不通过

您的代码已保存
答案错误:您提交的程序没有通过所有的测试用例
case通过率为0.00%

用例:
CJFRR8pYzTjcMy860OS96WRU9C9XjNW178n1FnFmpNcUvrS

对应输出应该为:

dkgss87z9u52n9860pt96xsv9d9y5ox17861g6g67o2v87t

你的输出为:

dkgss8z un 860pt96xsv9d9yox1781ggovt

解析:

string中的push_back函数,作用是字符串之后插入一个字符。

猜你喜欢

转载自blog.csdn.net/linyuhan3232/article/details/89702823
今日推荐