首页 > 试题广场 >

参数与艺术

[编程题]参数与艺术
  • 热度指数:311 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
为了确保智加科技的智能驾驶重卡能够满足各类运输要求,工程师阿文跟着测试车队开始了在中国国道上的驰骋,他敏锐的发现其车辆的参数配置文件采用带有相对路径的树状层次结构进行组织,如以下结构所示(缩进为两个空格字符):
/P1:v1
  Q1:v2
    R1:v3
    R2:v4
/P2:v5
那么,随着测试以及量产车辆的增多需要使用集中式的参数服务器来管理配置,这也意味着将原有的配置文件导入到参数服务器在参数服务器中,参数采用Key-Value的形式进行组织。需将上述格式的配置文件转化成如下形式:
/P1:v1
/P1/Q1:v2
/P1/Q1/R1:v3
/P1/Q1/R2:v4
/P2:v5
请用程序实现以上过程输入为原始带有相对路径的配置文件,输出为平铺展开的配置文件。


输入描述:
输入为层次结构配置文件读入到内存的字符串。


输出描述:
输出为平铺完的字符串。
示例1

输入

/P1:v1
  Q1:v2
    R1:v3
    R2:v4
/P2:v5
#

输出

/P1:v1
/P1/Q1:v2
/P1/Q1/R1:v3
/P1/Q1/R2:v4
/P2:v5
#
示例2

输入

/P1:
  Q1:v2
#

输出

/P1/Q1:v2
#
示例3

输入

/P1:
#

输出

#

备注:
1. 输入的所有字符均为英文字符。
2. 每一行字符串中间和结尾均没有多余的空格字符。
3. 输入和输出数据没有空白行。
4. Key-Value模式的结果中没有空字符串的value。
5. 为了方便在线judge,在输入输出的字符的结尾都增加一个“#”字符。

模拟

用一个栈按深度从小到大的顺序保存上级所有目录,按输入顺序遍历路径,如果当前路径的深度比上一条大,直接拼接上前缀;否则弹栈退回到同层级目录后再拼接前缀。
line = input()
prefix = []      # 路径前缀
prevDepth = 0
while line != "#":
    lstripLine = line.lstrip()
    depth = (len(line) - len(lstripLine)) >> 1
    if depth == 0:
        prefix.clear()      # 前面没有空格,当前是第0层目录,重新开启前缀
    elif depth <= prevDepth:
        d = depth
        while d <= prevDepth:
            prefix.pop()        # 当前目录不比上一条的级别低,则返回上级
            d += 1
    prevDepth = depth
    pair = lstripLine.split(":")
    prefix.append(pair[0])
    if pair[1]:
        print("/".join(prefix) + ":" + pair[1])
    line = input()
print("#")

发表于 2022-04-08 13:15:09 回复(0)
import java.util.*;
public class Main{
 
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        String ans = new String();
        String head = new String();
 
        int lastCount = 0;
        while(sc.hasNext()){
            String str = sc.nextLine();
 
            if (str.equals("#")){
                System.out.println("#");
                return;
            }
 
            char[] target = str.toCharArray();
            //统计空格数量
            int spaceCount = 0;
            for (int i = 0; i < target.length; i++) {
                if (target[i] == ' '){
                    spaceCount++;
                }
            }
            if (str.startsWith("/")){
                head = str.trim().substring(0, 3);
                lastCount = 0;
                if (str.length() > 4){
                    System.out.println(str);
                }
            }else {
                //拼接上一个头
                if (spaceCount > lastCount){
                    System.out.println(head +"/"+str.trim());
                    lastCount = spaceCount;
                    head = head + "/" + str.trim().substring(0,2);
                }else {
 
                    if (spaceCount == lastCount){
                        System.out.println(head.substring(0,head.length() - 2) + str.trim());
                        head = head.substring(0,head.length() - 2) + str.trim().substring(0,2);
                    }else {
 
                        //重新计算头
                          int deleteCount =  (lastCount - spaceCount) / 2 ;
                          for (int i = 0; i < deleteCount + 1; i++) {
                            head =  head.substring(0,head.length() - 3);
                          }
                            System.out.println(head +"/"+str.trim());
                            head = head + "/" + str.trim().substring(0,2);
                            lastCount = spaceCount;
                    }
                }
            }
        }
 
    }
}


发表于 2021-03-15 22:43:24 回复(0)
#include <iostream>
#include <string>
#include <vector>
using namespace std;

pair<int, int> findThePathLevel(const string& path) {
    int spaceCount = 0, ColonPos = 0;
    for(const auto& it : path) {
        if(it == ' ') ++spaceCount;
        if(it != ':') {++ColonPos;}
        else break;
    }
    return {spaceCount, ColonPos};
}

int main() {
    string str;
    vector<string> pathVector;
    while(true) {
        getline(cin, str);    
        if(str == "#") { cout << str; break;}
        pair<int, int> res = findThePathLevel(str);
        int spaceCount = res.first / 2;
        int ColonPos = res.second;
        if(spaceCount == 0) {
            if(pathVector.size() != 0) {
                pathVector.clear();
            }
            pathVector.emplace_back(str.substr(0, ColonPos));
            if(str.size() != ColonPos+1)
                cout << str << endl;
        }
        else {
            string lastPath = pathVector[spaceCount - 1];
            //cout << "lastpath = " << lastPath << endl;
            string CurPath = lastPath + '/' + str.substr(res.first);
            if(str.size() != ColonPos + 1)
                cout << CurPath << endl;
            if(pathVector.size() < spaceCount + 1) {
                pathVector.emplace_back(lastPath + '/' + str.substr(spaceCount+1, ColonPos-res.first));
            }
            else {
                pathVector[spaceCount] = lastPath + '/' + str.substr(spaceCount+1, ColonPos-res.first);
            }
        }
    }
    return 0;
}
// 64 位输出请用 printf("%lld")

发表于 2023-10-10 16:14:32 回复(0)
/*  利用栈记录前缀
 */
import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner scan=new Scanner(System.in);
        List<String> ans=new ArrayList<>();
        Deque<String> stack=new LinkedList<>();
        String[] keyValue;
        String str;
        int depth=0;// 当前字符串的深度
        int stackDepth=0; // 栈的深度:记录前缀
        while(scan.hasNextLine()){
            str=scan.nextLine();
                    if(str.equals("#")){
                 ans.add("#");
                 break;
                    }
            depth=(str.length()-str.trim().length())>>1; 
            if(depth==0){
                // 深度为0时,清空栈中的内容
                stack.clear();
                keyValue=str.trim().split(":");
                stack.addLast(keyValue[0]);
                if(keyValue.length>1) {
                    ans.add(str);
                }
                stackDepth=depth;
                continue;
                
                
            }else if(depth<=stackDepth) {
                // 若当前字符串的深度小于栈深度,出栈,直到栈中元素小于当前字符串深度
                while(depth<=stackDepth) {
                    stack.pollLast();
                    stackDepth--;
                }
            }
            StringBuilder sb=new StringBuilder();
            keyValue=str.trim().split(":");
            stack.addLast("/"+keyValue[0]);
            stackDepth=depth;
            if(keyValue.length>1) {
                for(String s:stack) {
                    sb.append(s);
                }
                ans.add(sb.toString()+":"+keyValue[1]);
            }
                
        }
        for(String s:ans){
            System.out.println(s);
         }
        
    }
}

编辑于 2022-09-21 20:38:03 回复(0)
#include <bits/stdc++.h>
using namespace std;

int main(){
    string s;
    vector<string> ans;
    vector<string> path;
    while(getline(cin, s)){
        if(s == "#"){
            break;
        }
        if(s[0] == '/'){
            path.clear();
            int idx = s.find(":");
            if(idx + 1 < s.size()){
                ans.push_back(s);
            }
            string head = s.substr(0, idx) + "/";
            path.push_back(head);
        }
        else{
            int backspace = 0;
            while(s[backspace] == ' '){
                ++backspace;
            }
            while(path.size() > (backspace/2)){
                path.pop_back();
            }
            int idx = s.find(":");
            int n = s.size();
            string head = s.substr(backspace, idx-backspace) + "/";
            if(idx + 1 < n){
                string path_join;
                for(int i=0; i < backspace/2; ++i){
                    path_join += path[i];
                }
                path_join += s.substr(backspace);
                ans.push_back(path_join);
            }
            path.push_back(head);
        }
    }
    for(auto str : ans){
        cout << str << endl;
    }
    cout << "#" << endl;

    return 0;
}

发表于 2022-08-24 21:34:21 回复(0)
import java.util.*;

public class Main{
    public static void main(String[] args){
        ArrayList<String> prefix=new ArrayList<String>();
        int stackPeek=0;
        Scanner in=new Scanner(System.in);
        int exblank=0;
        while(true){
            String thisLine=in.nextLine();
            if(thisLine.equals("#"))    break;
            for(exblank=0;thisLine.charAt(exblank)==' ';exblank++);
            while(exblank<stackPeek*2){
                stackPeek--;
                prefix.remove(stackPeek);//栈弹出;直到深度小于当前一级;
            }
            String temp=thisLine.substring(exblank,thisLine.length());
            String temps[]=temp.split(":");//前缀压入栈;
            if(stackPeek==0)
            	prefix.add(temps[0]);
            else
            	prefix.add('/'+temps[0]);
            stackPeek++;
            if(temps.length==1) {//如:后没有文件,则跳过输出部分;
            	continue;
            }
            for(String it:prefix){//输出前缀;
                System.out.print(it);
            }
            System.out.printf(":%s\n",temps[1]);
        }
        System.out.printf("#");
        return;
    }
}

发表于 2022-04-14 19:07:47 回复(0)
let line
let answer = []  // 存储当前路径所对应的完整的相对路径
let prefix = []
while(line = readline()) {
    if (line === '#') {
        answer.push(line)
        break
    }
    if (line[0] === '/') {
        prefix = []  // 清空前边保存的路径前缀信息
        // 保存此时路径中的前缀信息 [不管当前路径下有没有选择文件,为后边服务]
        prefix.push(line.slice(0, line.indexOf(':')))
        if (line.indexOf(':') + 1 < line.length) {
            answer.push(line) //当前路径有文件,直接存储当前路径
        }
        continue
    }

    // 以空格开头的路径
    let space = 0
    while(line[space] === ' ') {
        space++ // 统计当前行的空格数量
    }
    if (prefix.length === space / 2) {
        prefix.push(prefix[space / 2 - 1] + '/' + line.slice(space, line.indexOf(':')))
    }
    let current = prefix[space / 2 - 1] + '/' + line.slice(space)
    answer.push(current)
}
for (let item of answer) {
    print(item)
}
发表于 2022-04-03 17:31:08 回复(0)

# Here is input 
endingstr = ''
l = 0
strinput = []
while endingstr != '#':
    strinput.append(input())
    endingstr = strinput[l]
    l += 1
# strinput = ['/P1:v1','  Q1:v2', '    R1:v3','/P2:v2','/P2','#']
# print(strinput)
strnum = len(strinput)
stroutput = []

for i in range(strnum):
    strlen = len(strinput[i])
    if strinput[i][0] == '/':
        pathheader = [] #reset header
        pathheader.append( strinput[i][0:3] + '/')
        if len(strinput[i])>4:
            stroutput.append(strinput[i])
    elif strinput[i][0] == ' ':
        k = 0 #count the space
        for j in range(len(strinput[i])):
            if strinput[i][j] == ' ':
                k+=1
        # clear all spaces
        strinput[i] = strinput[i].replace(' ','')
        # get the sub header
        pathheader.append(strinput[i][0:2] + '/')
        # join the current string with header
        joinedheader = []
        for j in range(0,int(k/2)):
            joinedheader.append(pathheader[j])
        joinedpath = ''.join(joinedheader) + strinput[i]
        # print(joinedpath)
        stroutput.append(joinedpath)
    elif strinput[i][0] == '#':
        stroutput.append('#')

# now set the print loop

for i in range(len(stroutput)):
    print(stroutput[i])





发表于 2021-07-07 17:55:42 回复(0)

#include <iostream>
#include <map>
#include <vector>
#include <cstring>
using namespace std;


int main(){
    map<int,string> dir_map_string;
    vector<string> ans;
    string input;
    while(getline(cin,input)){
        if(input == "#") break;
        if(input[0]=='/'){
            dir_map_string.clear();
            if((input.find(":")+1)<input.size())
            ans.push_back(input);
            dir_map_string[0]=input.substr(0,input.find(":"));
            continue;
        }
        int blackspace = 0;
        while(input[blackspace++]==' ');    //统计空格
        int dir_base = (blackspace-1)/2-1;
        string ans_string = dir_map_string[dir_base] + "/" + input.substr(blackspace-1,input.size()-blackspace+1);
        dir_map_string[(blackspace-1)/2] = ans_string.substr(0,ans_string.find(":"));
        ans.push_back(ans_string);
    }
    for(auto s : ans){
        cout<<s<<endl;
    }
    cout<<"#"<<endl;
    return 0;
}

发表于 2021-03-18 11:52:53 回复(0)
/*
输入例子:
/P1:v1
  Q1:v2
    R1:v3
    R2:v4
/P2:v5
#
*/

/*
/P1:v1
/P1/Q1:v2
/P1/Q1/R1:v3
/P1/Q1/R2:v4
/P2:v5
#
*/

#include <vector>
#include <map>
#include <string>
#include <iostream>

using namespace std; 

int main()
{
    string strInput;
    
    map<int, int> kongge;   //每行存储多少空格
    map<int, string> values;   //每行存储的字符
    int i = 0;


    while (getline(cin, strInput))
    {
          if (strInput == "#")
        {
            break;
        }
        
        //统计空格数量
        int nCount = 0;
        int npos = 0;
        string strTemp = strInput;
        while (npos != -1)
        {
            npos = strTemp.find(' ');
            if (npos == -1)
            {
                break;
            }
            strTemp = strTemp.substr(npos + 1, strTemp.size() - npos - 1);
            nCount++;
        }
        //统计每行中空格的数量
        kongge.insert(pair<int, int>(i, nCount));
        //统计每行中字符
        values.insert(pair<int, string>(i, strTemp));
        i++;
    }

    //遍历每行元素中的空行
    //取出第一行中的
    map<int, string> ans;
    //插入第一行的
    ans.insert(pair<int, string>(0, values[0]));
    for (int i = 1; i < kongge.size(); i++)
    {
        int nlastkongge = kongge[i-1];
        int ncurkongge = kongge[i];
        int nabs = ncurkongge - nlastkongge;

        string strlastvalues = values[i - 1];
        string strcurvalues = values[i];

        if (nabs >= 2)
        {
            //截取上一行中的2个字符
            string str2last = strlastvalues.substr(0, 2);
            string tmp = str2last + '/' + strcurvalues;
            ans.insert(pair<int, string>(i, tmp));
        }
        else
        {
            //否则值不变
            ans.insert(pair<int, string>(i, strcurvalues));
        }

    }
    return 0;
}

发表于 2021-03-16 14:54:07 回复(1)

热门推荐

通过挑战的用户