1. 程式人生 > >PAT 1108 Finding Average [難]

PAT 1108 Finding Average [難]

1108 Finding Average (20 分)

The basic task is simple: given N real numbers, you are supposed to calculate their average. But what makes it complicated is that some of the input numbers might not be legal. A legal input is a real number in [1000,1000] and is accurate up to no more than 2 decimal places. When you calculate the average, those illegal numbers must not be counted in.

Input Specification:

Each input file contains one test case. For each case, the first line gives a positive integer N (100). Then N numbers are given in the next line, separated by one space.

Output Specification:

For each illegal input number, print in a line ERROR: X is not a legal number

 where X is the input. Then finally print in a line the result: The average of K numbers is Y where K is the number of legal inputs and Y is their average, accurate to 2 decimal places. In case the average cannot be calculated, output Undefined instead of Y
. In case K is only 1, output The average of 1 number is Y instead.

Sample Input 1:

7
5 -3.2 aaa 9999 2.3.4 7.123 2.35

Sample Output 1:

ERROR: aaa is not a legal number
ERROR: 9999 is not a legal number
ERROR: 2.3.4 is not a legal number
ERROR: 7.123 is not a legal number
The average of 3 numbers is 1.38

Sample Input 2:

2
aaa -9999

Sample Output 2:

ERROR: aaa is not a legal number
ERROR: -9999 is not a legal number
The average of 0 numbers is Undefined

 題目大意:給出n個數,可能不是合法的,給出那些合法的數的平均值。

//我的天哪,這個題也太難了吧,難死我了,改了好多遍我為什麼就是寫不對?越改通過的測試點越少。。絕望。

#include <iostream>
#include <algorithm>
#include<cstdio>
#include<stdio.h>
#include <queue>
#include<cmath>
#include <vector>
#include<set>
using namespace std;

//float toNum(string s){
//    //有小數怎麼辦?有點絕望,好像沒有做過這樣的題目。
//    int pos=s.find(".");
//    float num=0;
//    for(int i=0;i<pos;i++){
//        num=num*10+(s[i]-'0');
//        n=atof()
//    }
//
//}

int main()
{
    int n;
    cin>>n;
    string s;
    vector<float> legal;
    vector<string> nolegal;
    for(int i=0; i<n; i++)
    {
        cin>>s;
        bool flag=true;
        for(int j=0; j<s.size(); j++) //判斷是否是字母
        {
            if(!(s[j]>='0'||s[j]<='9')||s[j]!='.'||!s[j]!='-')//只能是這幾種。
            {
                flag=false;
                break;//比如2..0這樣的算是合法數字嗎?這就很尷尬,我感覺不是。
            }
            if((s[j]=='-'&&j)|(s[j]=='-'&&j==0&&s.size()==1)){//加上這個,並沒有通過1和4測試點。
                flag=false;break;
            }
        }
        if(s.find(".")!=string::npos)
        {
            int pos=s.find(".");
            if(s.size()-1>3||pos==0)//如果小數點出現在第一個也是不合法的,加上這個之後還是沒通過14測試點。
            {
                flag=false;
            }
            if(s.find(".",pos+1)!=string::npos)
            {
                flag=false;
            }
        }
        float numf;
        if(flag)
        {
            numf=atof(s.c_str());
            if(numf>1000.0||numf<-1000.0)
            {
                nolegal.push_back(s);
            }
            else
            {
                legal.push_back(numf);
            }
        }
        else
        {
            nolegal.push_back(s);
        }

    }
    for(int i=0; i<nolegal.size(); i++)
    {
        printf("ERROR: %s is not a legal number\n",nolegal[i].c_str());
    }
    if(legal.size()==0)
    {
        printf("The average of 0 numbers is Undefined");
    }
    else if(legal.size()==1)
    {
        printf("The average of 1 number is %.2f",legal[0]);
    }
    else
    {
        float sum=0;
        int size=legal.size();
        for(int i=0; i<size; i++)
            sum+=legal[i];
        printf("The average of %d number is %.2f",size,sum/size);
    }
    return 0;
}
//1,沒有判斷-是否在首位,如:1-6就視為合法了。。
//2.只有一個.時,是不合法的。。
//3.測試了-,發現自己的程式碼認為是合法的。。。絕望,好複雜。。。
//4.發現了要給十分嚴重的問題,就是如果它的非法輸入不一定非得是字母。。。

 

 //我也不知道這是為什麼通不過。。。哭遼。

學習了柳神的程式碼:

參考:https://www.cnblogs.com/lanjianhappy/p/6861728.html

 sscanf(輸入的字串,格式,輸出到);

scanf是從鍵盤輸入,而sscanf讀入的是第一個引數,是個字串。

發現這裡第三個引數根本就沒有型別限制!!!

Int sscanf( string str, string fmt, mixed var1, mixed var2 ... );
  int scanf( const char *format [,argument]... );

 

char buf[512] = ;
  sscanf("123456 ", "%s", buf);
  printf("%s/n", buf);
  結果為:123456
sscanf("123456 ", "%4s", buf);
  printf("%s/n", buf);
  結果為:1234
sscanf("123456abcdedfBCDEF", "%[1-9a-z]", buf);
  printf("%s/n", buf);
  結果為:123456abcdedf

 

 就是類似於正則表示式!

sprinf()學習:http://www.runoob.com/cprogramming/c-function-sprintf.html

C 庫函式 int sprintf(char *str, const char *format, ...) 傳送格式化輸出到 str 所指向的字串。

#include <stdio.h>
#include <math.h>

int main()
{
   char str[80];

   sprintf(str, "Pi 的值 = %f", M_PI);
   puts(str);
   
   return(0);
}

Pi 的值 = 3.141593

 

應該是從後往前看,先將第三個引數第二個引數的格式賦值,然後再整體賦值給第一個引數。

當然第一個引數和上一個函式一樣都是字串。

int main()
{
    string s;
    char a[50];
    float temp;
    cin>>s;
    sscanf(s.c_str(),"%f",&temp);
    sprintf(a,"%.2f",temp);
    cout<<s<<'\n';
    cout<<a<<'\n';
    cout<<temp;
    return 0;
}

 

學習了!

柳神的程式碼真的是太厲害了。

多複習!