classPoly{friendPolyoperator+(constPoly&lhs,constPoly&rhs){Polyres(lhs);for(constauto&[term,coef]:rhs.terms)res.terms[term]+=coef;returnres;}friendPolyoperator-(constPoly&lhs,constPoly&rhs){Polyres(lhs);for(constauto&[term,coef]:rhs.terms)res.terms[term]-=coef;returnres;}friendPolyoperator*(constPoly&lhs,constPoly&rhs){Polyres;for(constauto&[a,aCoef]:lhs.terms)for(constauto&[b,bCoef]:rhs.terms)res.terms[merge(a,b)]+=aCoef*bCoef;returnres;}// Friend ostream& operator<<(ostream& os, const Poly& poly) {// os << "{";// for (const auto& [term, coef] : poly.terms)// os << term << ": " << coef << ", ";// os << "}";// return os;// }public:vector<string>toList(){vector<string>res;vector<string>keys;for(constauto&[term,_]:terms)keys.push_back(term);sort(begin(keys),end(keys),[&](constauto&a,constauto&b){// Smallest degree is the lastif(a=="1")returnfalse;if(b=="1")returntrue;constvector<string>as=split(a,'*');constvector<string>bs=split(b,'*');// Largest degree is the first// Breaking ties by lexicographic orderreturnas.size()==bs.size()?a<b:as.size()>bs.size();});autoconcat=[&](conststring&term)->string{if(term=="1")returnto_string(terms[term]);returnto_string(terms[term])+'*'+term;};for(conststring&key:keys)if(terms[key])res.push_back(concat(key));returnres;}Poly()=default;Poly(conststring&term,intcoef){terms[term]=coef;}private:unordered_map<string,int>terms;// E.g. merge("a*b", "a*c") -> "a*a*b*c"staticstringmerge(conststring&a,conststring&b){if(a=="1")returnb;if(b=="1")returna;stringres;vector<string>A=split(a,'*');vector<string>B=split(b,'*');inti=0;// A's indexintj=0;// B's indexwhile(i<A.size()&&j<B.size())if(A[i]<B[j])res+='*'+A[i++];elseres+='*'+B[j++];while(i<A.size())res+='*'+A[i++];while(j<B.size())res+='*'+B[j++];returnres.substr(1);}staticvector<string>split(conststring&token,charc){vector<string>vars;istringstreamiss(token);for(stringvar;getline(iss,var,c);)vars.push_back(var);returnvars;}};classSolution{public:vector<string>basicCalculatorIV(stringexpression,vector<string>&evalvars,vector<int>&evalints){vector<string>tokens=getTokens(expression);unordered_map<string,int>evalMap;for(inti=0;i<evalvars.size();++i)evalMap[evalvars[i]]=evalints[i];for(string&token:tokens)if(evalMap.count(token))token=to_string(evalMap[token]);constvector<string>&postfix=infixToPostfix(tokens);returnevaluate(postfix).toList();}private:vector<string>getTokens(conststring&s){vector<string>tokens;inti=0;for(intj=0;j<s.length();++j)if(s[j]==' '){if(i<j)tokens.push_back(s.substr(i,j-i));i=j+1;}elseif(string("()+-*").find(s[j])!=string::npos){if(i<j)tokens.push_back(s.substr(i,j-i));tokens.push_back(s.substr(j,1));i=j+1;}if(i<s.length())tokens.push_back(s.substr(i));returntokens;}boolisOperator(conststring&token){returntoken=="+"||token=="-"||token=="*";}vector<string>infixToPostfix(constvector<string>&tokens){vector<string>postfix;stack<string>ops;autoprecedes=[](conststring&prevOp,conststring&currOp)->bool{if(prevOp=="(")returnfalse;returnprevOp=="*"||currOp=="+"||currOp=="-";};for(conststring&token:tokens)if(token=="("){ops.push(token);}elseif(token==")"){while(ops.top()!="(")postfix.push_back(ops.top()),ops.pop();ops.pop();}elseif(isOperator(token)){while(!ops.empty()&&precedes(ops.top(),token))postfix.push_back(ops.top()),ops.pop();ops.push(token);}else{// IsOperand(token)postfix.push_back(token);}while(!ops.empty())postfix.push_back(ops.top()),ops.pop();returnpostfix;}Polyevaluate(constvector<string>&postfix){vector<Poly>polys;for(conststring&token:postfix)if(isOperator(token)){constPolyb=polys.back();polys.pop_back();constPolya=polys.back();polys.pop_back();if(token=="+")polys.push_back(a+b);elseif(token=="-")polys.push_back(a-b);else// Token == "*"polys.push_back(a*b);}elseif(token[0]=='-'||all_of(begin(token),end(token),[](charc){returnisdigit(c);})){polys.push_back(Poly("1",stoi(token)));}else{polys.push_back(Poly(token,1));}returnpolys[0];}};
classPoly{publicPolyadd(Polyo){for(finalStringterm:o.terms.keySet())terms.merge(term,o.terms.get(term),Integer::sum);returnthis;}publicPolyminus(Polyo){for(finalStringterm:o.terms.keySet())terms.merge(term,-o.terms.get(term),Integer::sum);returnthis;}publicPolymult(Polyo){Polyres=newPoly();for(finalStringa:terms.keySet())for(finalStringb:o.terms.keySet())res.terms.merge(merge(a,b),terms.get(a)*o.terms.get(b),Integer::sum);returnres;}// @Override// Public String toString() {// StringBuilder sb = new StringBuilder();// sb.append("{");// for (final String term : terms.keySet())// sb.append(term).append(": ").append(terms.get(term)).append(", ");// sb.append("}");// return sb.toString();// }publicList<String>toList(){List<String>res=newArrayList<>();List<String>keys=newArrayList<>(terms.keySet());Collections.sort(keys,newComparator<String>(){@Overridepublicintcompare(finalStringa,finalStringb){// Smallest degree is the lastif(a.equals("1"))return1;if(b.equals("1"))return-1;String[]as=a.split("\\*");String[]bs=b.split("\\*");// Largest degree is the first// Breaking ties by lexicographic orderreturnas.length==bs.length?a.compareTo(b):bs.length-as.length;}});for(finalStringkey:keys)if(terms.get(key)!=0)res.add(concat(key));returnres;}publicPoly(){}publicPoly(finalStringterm,intcoef){terms.put(term,coef);}privateMap<String,Integer>terms=newHashMap<>();// E.g. merge("a*b", "a*c") -> "a*a*b*c"privatestaticStringmerge(finalStringa,finalStringb){if(a.equals("1"))returnb;if(b.equals("1"))returna;StringBuildersb=newStringBuilder();String[]A=a.split("\\*");String[]B=b.split("\\*");inti=0;// A's indexintj=0;// B's indexwhile(i<A.length&&j<B.length)if(A[i].compareTo(B[j])<0)sb.append("*").append(A[i++]);elsesb.append("*").append(B[j++]);while(i<A.length)sb.append("*").append(A[i++]);while(j<B.length)sb.append("*").append(B[j++]);returnsb.substring(1).toString();}privateStringconcat(finalStringterm){if(term.equals("1"))returnString.valueOf(terms.get(term));returnnewStringBuilder().append(terms.get(term)).append('*').append(term).toString();}}classSolution{publicList<String>basicCalculatorIV(Stringexpression,String[]evalvars,int[]evalints){List<String>tokens=getTokens(expression);Map<String,Integer>evalMap=newHashMap<>();for(inti=0;i<evalvars.length;++i)evalMap.put(evalvars[i],evalints[i]);for(inti=0;i<tokens.size();++i)if(evalMap.containsKey(tokens.get(i)))tokens.set(i,String.valueOf(evalMap.get(tokens.get(i))));List<String>postfix=infixToPostfix(tokens);returnevaluate(postfix).toList();}privateList<String>getTokens(finalStrings){List<String>tokens=newArrayList<>();inti=0;for(intj=0;j<s.length();++j)if(s.charAt(j)==' '){if(i<j)tokens.add(s.substring(i,j));i=j+1;}elseif("()+-*".contains(s.substring(j,j+1))){if(i<j)tokens.add(s.substring(i,j));tokens.add(s.substring(j,j+1));i=j+1;}if(i<s.length())tokens.add(s.substring(i));returntokens;}privatebooleanisOperator(finalStringtoken){returntoken.equals("+")||token.equals("-")||token.equals("*");}privatebooleanprecedes(finalStringprevOp,finalStringcurrOp){if(prevOp.equals("("))returnfalse;returnprevOp.equals("*")||currOp.equals("+")||currOp.equals("-");}privateList<String>infixToPostfix(List<String>tokens){List<String>postfix=newArrayList<>();Deque<String>ops=newArrayDeque<>();for(finalStringtoken:tokens)if(token.equals("(")){ops.push(token);}elseif(token.equals(")")){while(!ops.peek().equals("("))postfix.add(ops.pop());ops.pop();}elseif(isOperator(token)){while(!ops.isEmpty()&&precedes(ops.peek(),token))postfix.add(ops.pop());ops.push(token);}else{// IsOperand(token)postfix.add(token);}while(!ops.isEmpty())postfix.add(ops.pop());returnpostfix;}privatePolyevaluate(List<String>postfix){LinkedList<Poly>polys=newLinkedList<>();for(finalStringtoken:postfix)if(isOperator(token)){finalPolyb=polys.removeLast();finalPolya=polys.removeLast();if(token.equals("+"))polys.add(a.add(b));elseif(token.equals("-"))polys.add(a.minus(b));else// Token == "*"polys.add(a.mult(b));}elseif(token.charAt(0)=='-'||token.chars().allMatch(c->Character.isDigit(c))){polys.add(newPoly("1",Integer.parseInt(token)));}else{polys.add(newPoly(token,1));}returnpolys.getFirst();}}
classPoly:def__init__(self,term:str=None,coef:int=None):iftermandcoef:self.terms=Counter({term:coef})else:self.terms=Counter()def__add__(self,other):forterm,coefinother.terms.items():self.terms[term]+=coefreturnselfdef__sub__(self,other):forterm,coefinother.terms.items():self.terms[term]-=coefreturnselfdef__mul__(self,other):res=Poly()fora,aCoefinself.terms.items():forb,bCoefinother.terms.items():res.terms[self._merge(a,b)]+=aCoef*bCoefreturnres# Def __str__(self):# res = []# for term, coef in self.terms.items():# res.append(term + ': ' + str(coef))# return '{' + ', '.join(res) + '}'deftoList(self)->List[str]:forterminlist(self.terms.keys()):ifnotself.terms[term]:delself.terms[term]defcmp(term:str)->tuple:# Smallest degree is the lastifterm=='1':return(0,)var=term.split('*')# Largest degree is the first# Breaking ties by lexicographic orderreturn(-len(var),term)defconcat(term:str)->str:ifterm=='1':returnstr(self.terms[term])returnstr(self.terms[term])+'*'+termterms=list(self.terms.keys())terms.sort(key=cmp)return[concat(term)forterminterms]def_merge(self,a:str,b:str)->str:ifa=='1':returnbifb=='1':returnares=[]A=a.split('*')B=b.split('*')i=0# A's indexj=0# B's indexwhilei<len(A)andj<len(B):ifA[i]<B[j]:res.append(A[i])i+=1else:res.append(B[j])j+=1return'*'.join(res+A[i:]+B[j:])classSolution:defbasicCalculatorIV(self,expression:str,evalvars:List[str],evalints:List[int])->List[str]:tokens=list(self._getTokens(expression))evalMap={a:bfora,binzip(evalvars,evalints)}fori,tokeninenumerate(tokens):iftokeninevalMap:tokens[i]=str(evalMap[token])postfix=self._infixToPostfix(tokens)returnself._evaluate(postfix).toList()def_getTokens(self,s:str)->Iterator[str]:i=0forj,cinenumerate(s):ifc==' ':ifi<j:yields[i:j]i=j+1elifcin'()+-*':ifi<j:yields[i:j]yieldci=j+1ifi<len(s):yields[i:]def_infixToPostfix(self,tokens:List[str])->List[str]:postfix=[]ops=[]defprecedes(prevOp:chr,currOp:chr)->bool:ifprevOp=='(':returnFalsereturnprevOp=='*'orcurrOpin'+-'fortokenintokens:iftoken=='(':ops.append(token)eliftoken==')':whileops[-1]!='(':postfix.append(ops.pop())ops.pop()eliftokenin'+-*':# IsOperator(token)whileopsandprecedes(ops[-1],token):postfix.append(ops.pop())ops.append(token)else:# IsOperand(token)postfix.append(token)returnpostfix+ops[::-1]def_evaluate(self,postfix:List[str])->Poly:polys:List[Poly]=[]fortokeninpostfix:iftokenin'+-*':b=polys.pop()a=polys.pop()iftoken=='+':polys.append(a+b)eliftoken=='-':polys.append(a-b)else:# Token == '*'polys.append(a*b)eliftoken.lstrip('-').isnumeric():polys.append(Poly("1",int(token)))else:polys.append(Poly(token,1))returnpolys[0]