Untitled

 avatar
unknown
plain_text
a year ago
7.2 kB
3
Indexable
#include<iostream>
#include<cctype>
#include<cstring>
using namespace std;

const int MAX_LENGTH = 1500;
//真的想不到要怎麼解只能採用暴力解了嗚嗚嗚
//基本上這個就是小孩勞作 剪剪貼貼就解完ㄌ...

int main()
{
    char inputString[MAX_LENGTH] = {0};
    cin.getline(inputString, MAX_LENGTH);
    char outputString[MAX_LENGTH] = {0};
    char *checkPointers = inputString;//用來記錄函式中處理位置的指標

    for(int i = 0; i < MAX_LENGTH; i++)//do first step process so there is no situation like " ""punct"" "
    {
        if(isblank(inputString[i]) != 0)//第 i + 1個是空白的話
        {
            if(isalnum(inputString[i + 1]) != 0)//再檢查他的下一個是不是文字或數字 是的話就留空格
            {
                strncat(outputString, checkPointers, &inputString[i] - checkPointers);//用指標的差值來決定要貼多少字
                for(int j = 0; j < MAX_LENGTH; j++)
                {
                    if(outputString[j] == '\0')
                    {
                        outputString[j] = ' ';//因為會strncat會貼在從第一個數過來的第一個\0上面所以透過更改\0的位置來控制空格
                        outputString[j + 1] = '\0';
                        break;
                    }
                }
            //cout << outputString << endl;
                checkPointers = &inputString[i+1];//更新一下位置的指標去決定下一條要切的位置
            }
            else if(ispunct(inputString[i + 1]) != 0)//是標點符號的話就先接在字上面
            {
                strncat(outputString, checkPointers, &inputString[i] - checkPointers);
                checkPointers = &inputString[i+1];
            }
        }
        else if(inputString[i+1] == '\0')//碰到\0就先跳出這個條件判斷
        {
            strncat(outputString, checkPointers, &inputString[i+1] - checkPointers);//記得要貼最後一個指標到\0之間的東西
            break;
		}
            
	}

    //cout << outputString << endl;

    for(int i = 0; i < MAX_LENGTH; i++) //把修改完的都丟到input裡面 (我都從input當中索引) 這樣也不用開太多陣列 就只是有點複雜
    {
        inputString[i] = outputString[i];
	}
    checkPointers = inputString;//重置
	outputString[0] = '\0';//把輸出陣列歸0

    for(int i = 0; i < MAX_LENGTH; i++)
    {
        if(ispunct(inputString[i - 1]) != 0 && isblank(inputString[i]) != 0)//這個也是先讓所有的標點符號先黏在一起 反正就是先讓標點符號的左右邊不要有任何的空格 影響判斷
        {
            strncat(outputString, checkPointers, &inputString[i] - checkPointers);
            checkPointers = &inputString[i+1];
        }
        else if(inputString[i + 1] == '\0')
        {
            strncat(outputString, checkPointers, &inputString[i + 1] - checkPointers);
            break;
		}
    }

    //cout << outputString << endl;

    for(int i = 0; i < MAX_LENGTH; i++) //把修改完的都丟到input裡面 (我都從input當中索引) 這樣也不用開太多陣列 就只是有點複雜
    {
        inputString[i] = outputString[i];
	}
    checkPointers = inputString;//重置
	outputString[0] = '\0';//把輸出陣列歸0

    for(int i = 0; i < MAX_LENGTH; i++)//碰到比較正常的標點符號後面就留白
    {
        if(inputString[i] == ',' || inputString[i] == '!' || inputString[i] == '.')//再來就是來檢查沒有任何奇怪條件的標點符號
        {
            strncat(outputString, checkPointers, &inputString[i + 1] - checkPointers);//都在它們後面留一格空格
                for(int j = 0; j < MAX_LENGTH; j++)
                {
                    if(outputString[j] == '\0')
                    {
                        outputString[j] = ' ';
                        outputString[j + 1] = '\0';
                        break;
                    }
                }
            checkPointers = &inputString[i+1];
        }
        else if(inputString[i + 1] == '\0')
        {
            strncat(outputString, checkPointers, &inputString[i + 1] - checkPointers);
            break;
		}
    }
    
    //cout << outputString << endl;

    for(int i = 0; i < MAX_LENGTH; i++) //把修改完的都丟到input裡面 (我都從input當中索引) 這樣也不用開太多陣列 就只是有點複雜
    {
        inputString[i] = outputString[i];
	}
    checkPointers = inputString;//重置
	outputString[0] = '\0';//把輸出陣列歸0

    for(int i = 0; i < MAX_LENGTH; i++)
    {
        if(isalnum(inputString[i]) != 0 && inputString[i + 1] == '(')//再來這個就是檢查左括號的段落了有左括弧就在她左邊留空格
        {
            strncat(outputString, checkPointers, &inputString[i + 1] - checkPointers);
            for(int j = 0; j < MAX_LENGTH; j++)
                {
                    if(outputString[j] == '\0')
                    {
                        outputString[j] = ' ';
                        outputString[j + 1] = '\0';
                        break;
                    }
                }
            checkPointers = &inputString[i+1];
        }
        else if(inputString[i + 1] == '\0')
        {
            strncat(outputString, checkPointers, &inputString[i + 1] - checkPointers);
            break;
		}
    }
    //cout << outputString << endl;
    for(int i = 0; i < MAX_LENGTH; i++) //把修改完的都丟到input裡面 (我都從input當中索引) 這樣也不用開太多陣列 就只是有點複雜
    {
        inputString[i] = outputString[i];
	}
    checkPointers = inputString;//重置
	outputString[0] = '\0';//把輸出陣列歸0

    for(int i = 0; i < MAX_LENGTH; i++)
    {
        if(inputString[i] == ')' && ispunct(inputString[i + 1]) == 0)//如果右括號旁邊不是標點符號的話 那他的右邊也要多一格空格
        {
            strncat(outputString, checkPointers, &inputString[i + 1] - checkPointers);
            for(int j = 0; j < MAX_LENGTH; j++)
                {
                    if(outputString[j] == '\0')
                    {
                        outputString[j] = ' ';
                        outputString[j + 1] = '\0';
                        break;
                    }
                }
            checkPointers = &inputString[i+1];
        }
        else if(inputString[i + 1] == '\0')
        {
            strncat(outputString, checkPointers, &inputString[i + 1] - checkPointers);
            break;
		}
    }
    for(int i = 0; i < MAX_LENGTH; i++)//如果原本的字串縮了太多的話那就會多印一些莫名其妙的東西 所以有任何會印奇怪的東西的條件都要去除掉 讓他提早結束就能印出符合需求的程式就完成ㄌ
    {
        if(outputString[i] == ' ' && outputString[i + 1] == ' ')
        {
            outputString[i + 1] = '\0';
            break;
        }
    }

    cout << outputString << endl;

    return 0;
}