洛谷学习总集2

Brakeintime / 2024-10-15 / 原文

洛谷代码学习总集 2

目录索引
  • P1067 输出多项式的字符串
  • P1098 将切片展开成完整字符串



P1067 输出多项式的字符串

思路:多项式由:系数,"x",""指数,组成。其中各项多项式间由"+"连接,如果系数/指数为1则不需要打印系数/""指数。特殊情况:读入1、末两项(指数为1和指数为0)针对特殊情况特殊处理.

  • 拼接字符串并不好玩( 除非使用sstream 😄 )
  • 首项前面不需要加号,末项后面不能有加号,至少需要特殊处理一个(或者在循环内做项数条件判断)
  • 0的时候可以直接跳过当前项
代码
#include<iostream>
using std::cin,std::cout;

std::string makeMonomial(const int base,const int pow){
    std::string Monomial{};
    if(base==1)
        Monomial+="";
    else if(base==-1)
        Monomial+="-";
    else 
        Monomial+=std::to_string(base);
    Monomial+="x";
    if(pow > 1){
        Monomial+="^";
        Monomial+=std::to_string(pow);    
    }
    if(base==0)         return "";
    else if(pow ==0)    return std::to_string(base);
    else                return Monomial;
}

std::string makePolynomial(const int counts){
    std::string Polynomial{};
    int base;
    cin>>base;
    Polynomial+=makeMonomial(base,counts);
    for (int i = counts-1; i >= 0 ; i--)
    {
        cin>>base;
        if(base>0) Polynomial+='+';
        Polynomial+=makeMonomial(base,i);
    }
    return Polynomial;
}

int main(){
    int n;
    cin>>n;
    cout<<makePolynomial(n);
}



P1098 将切片展开成完整字符串

思路:检测"-",然后看前后字符是否满足要求。按照ASCII码自增/自减填充的字符就可以按顺序输出序列(再加一个内循环就可以重复输出,条件判断来确定是输出ASCII字符还是只输出"*")。

  • 注意溢出
  • 使用迭代器如果搭配replace方法注意小心地址越界,replace是深拷贝,会导致内存地址变化,迭代器在replace后就不能正常工作了!
  • 可以构建一个字符串,这样可以实现动态变化,但是也可以实时输出,会更快占用更少的内存
    奇怪的注意点
  • 字符串对象实质是类,[构建一个字符串]/[传递字符串参数]的速度略低,所以尽可能少构建字符串类对象可以优化一些速度
  • 可以使用 std::string& 也就是引用,类似指针,你对传参过来的字符串操作会影响原字符串(注意安全!)
  • 如果你喜欢cpp17,其更新了一个std::string_view对象,对于只读场景有更好的性能(具体可以自行了解:D )
构建串串
#include<iostream>
using std::cin,std::cout;


inline bool isInteger(char a){
	if(a>='0'&&a<='9') return true;
	else return false;
}

inline char Conv(int a){
	return (a+'0');
}
inline int  Conv(char a){
	return (a-'0');
}


/*
 * UorL == 1 => fill lowers;
 * UorL == 2 => fill uppers;
 * UorL == 3 => fill '*';
 * 
 * repeat means how many times the char would be repeat filled
 * 
 * revert == 1 => filled normally
 * revert == 2 => filled reversely 
 */
std::string filling(char left,char right, int UorL, int repeat, int revert){
//	int size = right - left;
	std::string filling;
	if(revert == 1)
	for (char t{char(left+1)}; right-t > 0 ;t++)
	{
		for (int j = 0; j < repeat; j++)
		{
			if(UorL==3){
				filling+='*';
			}
			else if(UorL==1||isInteger(left)){ //single-side detect since already checked outside;
				filling+=t;
			}
			else if(UorL==2){
				filling+=toupper(t);
			}
		}
		
	}
	if(revert == 2)
	for (char t{char(right-1)}; t-left > 0 ;t--)
	{
		for (int j = 0; j < repeat; j++)
		{
			if(UorL==3){
				filling+='*';
			}
			else if(UorL==1||isInteger(left)){ //single-side detect since already checked outside;
				filling+=t;
			}
			else if(UorL==2){
				filling+=toupper(t);
			}
		}
		
	}
	return filling;
	
}



//UorL == Upper or Lower
std::string extendString(std::string& input,int UorL = 1,int repeat = 1,int revert = 1){
	char left,right;
	std::string output;
	std::string::iterator it = input.begin();it++;
	while(it-1<input.end()){
		left  = *(it-1);
		right = *(it+1);
		output+=left;
		if(*it=='-'){
			if(!(islower(left)&&islower(right))&&!(isInteger(left)&&isInteger(right))){
				it++;
				continue;
			}
			if(right - left == 1){
				//input.erase(it);
				it++;
			}
			//if(*it=='c'){;}
			else if((right - left)>1){
				//input.replace(it,it+1,filling(left,right,UorL,repeat,revert));//filling(left,right,UorL,repeat,revert)
				output+=filling(left,right,UorL,repeat,revert);
				it++;
			}
		}
		it++;
	}
	return output;
}


int main(){
	std::string input;

	int p1,p2,p3;
	cin>>p1>>p2>>p3;
	cin>>input;
	cout<<extendString(input,p1,p2,p3);

	return 0;
}
实时输出
#include<iostream>
using std::cin,std::cout;


inline bool isInteger(char a){
	if(a>='0'&&a<='9') return true;
	else return false;
}

inline char Conv(int a){
	return (a+'0');
}
inline int  Conv(char a){
	return (a-'0');
}


/*
 * UorL == 1 => fill lowers;
 * UorL == 2 => fill uppers;
 * UorL == 3 => fill '*';
 * 
 * repeat means how many times the char would be repeat filled
 * 
 * revert == 1 => filled normally
 * revert == 2 => filled reversely 
 */
void filling(char left,char right, int UorL, int repeat, int revert){
	if(revert == 1)
	for (char t{char(left+1)}; right-t > 0 ;t++)
	{
		for (int j = 0; j < repeat; j++)
		{
			if(UorL==3){
				cout<<'*';
			}
			else if(UorL==1||isInteger(left)){ //single-side detect since already checked outside;
				cout<<t;
			}
			else if(UorL==2){
				cout<<char(toupper(t));
			}
		}
		
	}
	if(revert == 2)
	for (char t{char(right-1)}; t-left > 0 ;t--)
	{
		for (int j = 0; j < repeat; j++)
		{
			if(UorL==3){
				cout<<'*';
			}
			else if(UorL==1||isInteger(left)){ //single-side detect since already checked outside;
				cout<<t;
			}
			else if(UorL==2){
				cout<<char(toupper(t));
			}
		}
		
	}
	return;
	
}



//UorL == Upper or Lower
void extendString(std::string& input,int UorL = 1,int repeat = 1,int revert = 1){
	char left,right;
	std::string::iterator it = input.begin();it++;
	while(it-1<input.end()){
		left  = *(it-1);
		right = *(it+1);
		cout<<left;
		if(*it=='-'){
			if(!(islower(left)&&islower(right))&&!(isInteger(left)&&isInteger(right))){
				it++;
				continue;
			}
			if(right - left == 1){
				it++;
			}
			else if((right - left)>1){
				filling(left,right,UorL,repeat,revert);
				it++;
			}
		}
		it++;
	}
	return;
}


int main(){
	std::string input;

	int p1,p2,p3;
	cin>>p1>>p2>>p3;
	cin>>input;
	extendString(input,p1,p2,p3);

	return 0;
}