hiho一下第107周《Give My Text Back》题目分析

6
0

题目大意

小Hi和小Ho为了准备英语的期末考试,找了很多英语的电子资料。但是由于U盘出了问题,导致资料内容变得很乱。于是小Hi和小Ho决定写一个程序去将所有的电子资料格式化。 已知每一份资料只包含大小写字母,‘ ’(空格), ‘,’(逗号),‘.’(句号)以及换行符。小Hi和小Ho希望整理后的资料为如下格式: - 每一句话都是以’.’结尾,每一段话都是以换行符结尾。 - 每一段开始没有空格。 - 每一个句子都是完整的,即至少包含1个单词,句末一定为‘.’(句号)。 - 每一句话只有首字母大写。 - 每句话内单词之间由1个空格隔开。 - 标点符号与前面的单词之间无空格,标点符号后有1个空格或换行符。 对于给定的资料,请你对其进行格式化,并输出格式化的结果。

解题思路

本题是一道字符串处理的题目,主要考察对于字符串的读入和输出。

首先我们需要一个字符一个字符的将所有的内容读入。在读取的过程中,我们以空格作为分隔符,将单词与标点符号提取出来。同时将所有的字母都小写化。

伪代码:

w = ""
While (text is not empty)
    c = getNextChar()
    If (c is letter) Then
        c = lowercase(c) // 小写化
        w = w + c // 累加单词
    Else
        If (w is not empty) Then
            // 此时若w不是空,则表示前面已经读取了一个单词
            // 将该单词加入文章元素的数组
            article.push(w)
            w = ""  // 重置w
        End If
        If (c is not space) Then
            // c为标点符号或换行符
            // 同时将读取到的符号也加入文章元素的数组
            article.push(c)
        End If
    End If
End While

最后得到的article数组,就是构成这篇文章所有的单词,标点符号和换行符。

然后我们根据article数组来输出格式化之后的文章:

firstWord = true
For i = 0 .. article.length
    If (article[i] is not word) Then
        // 如果是符号,直接输出
        output article[i]
        If (article[i] == '.') Then
            // 如果该符号为句号,则下一个单词是新的一句话开始
            firstWord = true
        End If
    Else
        // article[i] 是单词
        If (firstWord) Then
            // 该单词为句首,大写化第一个字母
            article[i][0] = uppercase(article[i][0])
            firstWord = false
        End If
        // 考虑是否先输出一个空格
        If (i > 0 && article[i - 1] is not '\n')
            // 若当前单词不是一段开始时,我们都需要输出一个空格
            output ' '
        End If
        output article[i]
    End If
End For

至此本题得到解决。

9 answer(s)

0

题目的输入格式是啥? 有没有通过的同学能给个标准的读取输入的方式。 我用cin>>noskipws>>c 读好像不行

  • while(scanf("%c", &c) != EOF) 或者 while(cin >> noskipws >> c) 都行

  • 可以用getchar(),读到(c=getchar())==EOF结束

  • cin>>noskipws>>c 可以的

  • G++用getline,一行一行处理,返回值为0即为输入结束

  • 添加评论
  • reply
0

请问编译结果是Compile Error,然后下面一片空白是什么意思? 代码如下:

#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Solution
{
    int main()
    {
        vector<string> input;
        string word="";
        char c;
        while (cin >> noskipws >> c)
        {
            if (isalpha(c))
            {
                if (c >= 'A'&&c <= 'Z')
                    c += 32;
                word += c;
            }   
            else
            {
                if (word != "")
                {
                    input.push_back(word);
                    word = "";
                }
                if (c != ' ')
                    input.push_back(to_string(c));
            }
        }

        int n = input.size();
        bool isFirst = true;
        for (int i = 0; i < n;i++)
        {
            if (input[i] == "44")
            {
                cout << ',';
            }   
            else if (input[i] == "46")
            {
                cout << '.';
                isFirst = true;
            }   
            else if (input[i] == "10")
            {
                cout << endl;
            }   
            else
            {
                if (i>0&& input[i-1]!="10")
                {
                    cout << " ";
                }
                if (isFirst)
                {
                    input[i] = to_string(toupper(input[i][0])) + input[i].substr(1);
                    isFirst = false;
                }
                cout << input[i];
            }
        }
        return 0;
    }
};
  • main函数不能放在class里

  • 非常感谢。进一步修改后AC了。 #include <iostream> #include <string> #include <vector> using namespace std; int main() { vector<string> input; string word = ""; char c; while (cin >> noskipws >> c) { if (isalpha(c)) { if (c >= 'A'&&c <= 'Z') c += 32; word += c; } else { if (word != "") { input.push_back(word); word = ""; } if (c != ' ') input.push_back(to_string(c)); } } int n = input.size(); bool isFirst = true; for (int i = 0; i < n; i++) { if (input[i] == "44") cout << ','; else if (input[i] == "46") { cout << '.'; isFirst = true; } else if (input[i] == "10") cout << endl; else { if (i>0 && input[i - 1] != "10") cout << " "; if (isFirst) { input[i][0] -= 32; isFirst = false; } cout << input[i]; } } return 0; }

  • 添加评论
  • reply
1

好难

0

输入字符串的结束标志应该是什么呢?

  • EOF。 while(scanf("%c", &c) != EOF) 或者 while(cin >> noskipws >> c) 都行

  • 添加评论
  • reply
0

按照上面分析的结果写出代码。AC

#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
    vector<string> input;
    string word = "";
    char c;
    while (cin >> noskipws >> c)
    {
        if (isalpha(c))
        {
            if (c >= 'A'&&c <= 'Z')
                c += 32;
            word += c;
        }
        else
        {
            if (word != "")
            {
                input.push_back(word);
                word = "";
            }
            if (c != ' ')
                input.push_back(to_string(c));
        }
    }

    int n = input.size();
    bool isFirst = true;
    for (int i = 0; i < n; i++)
    {
        if (input[i] == "44")
            cout << ',';
        else if (input[i] == "46")
        {
            cout << '.';
            isFirst = true;
        }
        else if (input[i] == "10")
            cout << endl;
        else
        {
            if (i>0 && input[i - 1] != "10")
                cout << " ";

            if (isFirst)
            {
                input[i][0] -= 32;
                isFirst = false;
            }
            cout << input[i];
        }
    }
    return 0;
}
0

我觉得这个用python写应该很容易呀,不知道为什么无法AC

def correct(str):
upper = True
space = False
word_list = str.split(' ')
while True:
    if not '' in word_list:
        break
    word_list.remove('')
sentence = ""
for word in word_list:
    if upper:
        if space:
            sentence = sentence + ' ' + word[0].upper()+word[1:].lower()
        else:
            sentence = sentence + word[0].upper()+word[1:].lower()
        upper = False
    elif word == ',' or word == '.':
        sentence = sentence + word
    else:
        sentence = sentence + ' ' + word.lower()
    if word == '.':
        upper = True
        space = True
return sentence

while True: try: line = raw_input() print correct(line) except EOFError: break

0

一直wrong answer是怎么回事啊,难道是读取数据不对?

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

using namespace std;

class Solution {
private:
    vector<string> &split(const string &s, char delim, vector<string> &elems) {
        stringstream ss(s);
        string item;
        while (getline(ss, item, delim)) {
            elems.push_back(item);
        }
        return elems;
    }

    vector<string> split(const string &s, char delim) {
        vector<string> elems;
        split(s, delim, elems);
        return elems;
    }

public:
    string process(const string s) {
        string originSen;
        bool isCapital = false;
        vector<string> rs;
        char delim = ' ';

        rs = split(s, delim);

        for (unsigned int i = 0; i < rs.size(); i++) {
            if (rs[i] != "") {
                if (rs[i] == ","){
                    originSen.append(",");
                }
                else if (rs[i] == "."){
                    originSen.append(". ");
                    isCapital = true;
                }
                else {
                    transform(rs[i].begin(), rs[i].end(), rs[i].begin(), ::tolower);
                    if (isCapital || i == 0) {
                        locale loc;
                        rs[i][0] = toupper(rs[i][0], loc);
                        originSen.append(rs[i]);
                    }
                    else {
                        originSen.append(" ");
                        originSen.append(rs[i]);
                    }
                }
            }
        }

        return originSen;
    }

};

int main() {
    vector<string> data;
    string tem;
    Solution s;

    getline(cin, tem);
    while (tem != "") {
        data.push_back(tem);
        getline(cin, tem);
    }

    for (unsigned int i = 0; i < data.size(); i++) {
        string rs = s.process(data[i]);
        cout << rs;

        if (i < data.size() - 1) cout << endl;
    }

    return 0;
}
0

也是按照分析写的代码,样例通过了,提交上去不对,不知道哪儿有问题啊 import java.util.*; public class Main{ public static void main(String[] args){

    Scanner scan = new Scanner(System.in);
    while(scan.hasNext()){
        String str = scan.nextLine();
        System.out.println(format(str));
    }
}
public static String format(String str){
    List<String> list = new ArrayList<String>();
    String s = new String();
    for(int i=0; i<str.length();i++){
        char ch ;
        if(str.charAt(i) >='A' && str.charAt(i)<='Z'){
            ch = (char)(str.charAt(i) + 32);
            s = s + String.valueOf(ch);
        }else if(str.charAt(i) == ',' || str.charAt(i) == '.'){
            if(s.length() > 0)
                list.add(new String(s));
            s = "";
            list.add(String.valueOf(str.charAt(i)));
        }else if(str.charAt(i) == ' '){
            if(s.length() > 0){
                list.add(new String(s));
                s = "";
            }
        }else {
            s = s + String.valueOf(str.charAt(i));
        } 
    }
    if(s.length() > 0)
        list.add(new String(s));
    String ans = uppercase(list.get(0));
    for(int i=1; i<list.size(); i++){
        if(list.get(i).equals(",") || list.get(i).equals(".")){
            ans = ans + list.get(i);
        }
        else if(list.get(i-1) == "."){
            ans = ans + " " + uppercase(list.get(i));
        }else 
            ans = ans + " " + list.get(i);          
    }
    return ans;
}
public static String uppercase(String str){
    char ch =  (char)(str.charAt(0) -32);
    String ans = String.valueOf(ch);
    for(int i=1;i<str.length();i++)
        ans = ans + String.valueOf(str.charAt(i));
    return ans;
}

}

  • 句子的开始不是每一行的开始,而是句号的结束,句号后面下一个单词才是大写首字母

  • 添加评论
  • reply
0

其于有三个地方可以插入空格,即:word and word,word and comma, word and period。

但是题目中有一个没有提到,就是在"."与换行符之间可能插入空格,所以题目没有描述清楚,有bug。

write answer 切换为英文 切换为中文


转发分享