C++ 为CONDOWN问题的选项添加操作
我正在尝试制作一个小程序来解决倒计时问题。基本上,给定一个数C++ 为CONDOWN问题的选项添加操作,c++,algorithm,c++11,C++,Algorithm,C++11,我正在尝试制作一个小程序来解决倒计时问题。基本上,给定一个数n和一个数向量,问题输出ifn可以通过简单的操作(比如加法、div、mult和subs)来构造。 可以不使用数字向量的所有元素,但每个数字最多只能使用一次 我试图给程序的输入是一个带反向波兰符号的字符串,所以我做了一个小函数来解决这类表达式 这是我的密码: #include <iostream> #include <stack> #include <string> #include <vecto
n
和一个数向量,问题输出ifn
可以通过简单的操作(比如加法、div、mult和subs)来构造。
可以不使用数字向量的所有元素,但每个数字最多只能使用一次
我试图给程序的输入是一个带反向波兰符号的字符串,所以我做了一个小函数来解决这类表达式
这是我的密码:
#include <iostream>
#include <stack>
#include <string>
#include <vector>
using namespace std;
bool is_number(const std::string& s) {
string::const_iterator it = s.begin();
while (it != s.end() && std::isdigit(*it)) ++it;
return !s.empty() && it == s.end();
}
vector<string> parseInput(const string& expression) {
vector<string> parsedInp;
string current = "";
for (auto token : expression) {
if (isdigit(token)) {
current += token;
}
else if (token == ' ') {
if (current != "") {
parsedInp.push_back(current);
current = "";
}
}
else {
parsedInp.push_back(string(1, token));
}
}
return parsedInp;
}
double operateExpression(const vector<string>& parsedInp) {
stack<double> expression;
for (auto token : parsedInp) {
if (is_number(token)) {
expression.push(stod(token));
}
else {
double op1 = expression.top();
expression.pop();
double op2 = expression.top();
expression.pop();
if (token == "+") {
expression.push(op1 + op2);
}
if (token == "-") {
expression.push(op1 - op2);
}
if (token == "*") {
expression.push(op1 * op2);
}
if (token == "/") {
expression.push(op1 / op2);
}
}
}
return expression.top();
}
string getSolution(vector<string> inp, const int target) {
vector<string> op = { "+", "-", "*", "/", "" };
//TODO....
}
int main() {
string expression;
getline(cin, expression);
vector<string> parsedInp = parseInput(expression);
cout << operateExpression(parsedInp) << endl;
}
所以现在的问题基本上归结为能够将所有可能的操作添加到矩阵中的每一个条目中,这就是我丢失的地方。
我知道暴力是不好的,但我只对这4个操作和6个值感兴趣。
我还担心组合爆炸…最后我想到了这个
#include <iostream>
#include <stack>
#include <string>
#include <vector>
#include <algorithm>
#include <set>
using namespace std;
using uint = unsigned int;
bool is_number(const std::string& s) {
string::const_iterator it = s.begin();
while (it != s.end() && std::isdigit(*it)) ++it;
return !s.empty() && it == s.end();
}
vector<string> parseInput(const string& expression) {
vector<string> parsedInp;
string current = "";
for (auto token : expression) {
if (isdigit(token)) {
current += token;
}
else if (token == ' ') {
if (current != "") {
parsedInp.push_back(current);
current = "";
}
}
else {
parsedInp.push_back(string(1, token));
}
}
return parsedInp;
}
bool isCorrectRPN(vector<string>& expression) {
int ssize = 0;
for (string token : expression) {
if (token == "+" or token == "-" or token == "/" or token == "*") {
ssize -= 1;
}
else if (token != " "){
ssize += 1;
}
if (ssize < 0) return false;
}
return ssize == 1;
}
double operateExpression(const vector<string>& parsedInp) {
stack<double> expression;
for (auto token : parsedInp) {
if (is_number(token)) {
expression.push(stod(token));
}
else if (token != " ") {
double op1 = expression.top();
expression.pop();
double op2 = expression.top();
expression.pop();
if (token == "+") {
expression.push(op1 + op2);
}
if (token == "-") {
expression.push(op2 - op1);
}
if (token == "*") {
expression.push(op1 * op2);
}
if (token == "/") {
expression.push(op2 / op1);
}
}
}
return expression.top();
}
void printValues(const vector<string>& val) {
for (auto a : val) {
cout << a;
}
cout << endl;
}
void choices(const vector<string>& values, vector<string>& currentSet, int& nVals, bool& finished, set<int>& valuesInUse, const int N) {
if (not finished) {
vector<string> op = { "+", "-", "*", "/", " "};
if (currentSet.size() and operateExpression(currentSet) == N) {
printValues(currentSet);
finished = true;
}
else if (nVals < values.size()) {
for (uint i = 0; i < values.size(); i++) {
if (valuesInUse.find(i) == valuesInUse.end()) {
valuesInUse.insert(i);
for (auto o : op) {
currentSet.push_back(values[i]);
currentSet.push_back(o);
nVals++;
if (isCorrectRPN(currentSet)) {
choices(values, currentSet, nVals, finished, valuesInUse, N);
}
nVals--;
currentSet.pop_back();
currentSet.pop_back();
}
valuesInUse.erase(i);
}
}
}
}
}
/*
bool hasSpace(const vector<string>& v) {
return v[v.size() - 1] == " ";
}
void cleanChoices(vector<vector<string>>& m) {
m.erase(std::remove_if(m.begin(), m.end(), hasSpace), m.end());
}*/
int main() {
//string expression;
//getline(cin, expression)
const vector<string> values = { "100","4","17","9","3","2" };
vector<string> currentSet;
int nVals = 0;
bool finished = false;
set<int> valuesInUse;
choices(values, currentSet, nVals, finished, valuesInUse, 37);
}
#包括
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
使用uint=unsigned int;
bool是_编号(常数std::string&s){
string::const_迭代器it=s.begin();
而(it!=s.end()&&std::isdigit(*it))++it;
return!s.empty()&&it==s.end();
}
向量解析输入(常量字符串和表达式){
向量parsedInp;
字符串current=“”;
for(自动标记:表达式){
if(isdigit(令牌)){
当前+=令牌;
}
else if(令牌==''){
如果(当前!=“”){
parsedInp.推回(当前);
当前=”;
}
}
否则{
parsedInp.push_back(字符串(1,标记));
}
}
返回parsedInp;
}
布尔isCorrectRPN(向量和表达式){
int-ssize=0;
for(字符串标记:表达式){
如果(令牌=“+”或令牌=“-”或令牌=“/”或令牌=“*”){
ssize-=1;
}
else if(令牌!=“”){
ssize+=1;
}
如果(ssize<0)返回false;
}
返回ssize==1;
}
双运算符表达式(const vector和parsedInp){
堆栈表达式;
for(自动令牌:parsedInp){
if(是_编号(令牌)){
push(stod(token));
}
else if(令牌!=“”){
double op1=expression.top();
表达式pop();
double op2=expression.top();
表达式pop();
如果(标记=“+”){
表达式.push(op1+op2);
}
如果(标记=“-”){
表达式.push(op2-op1);
}
如果(标记=“*”){
表达式.push(op1*op2);
}
如果(标记=“/”){
表达式.push(op2/op1);
}
}
}
返回表达式.top();
}
无效打印值(常量向量和值){
用于(自动a:val){
库特
tot表示我们可以选择一系列数字的方式总数
vector<int>arr;
for(int j=0;j<60;j++){
if(i&(1<<j) && j<vec.size()) //checking if particular bit is set.
arr.push_back(vec[j]); //if its set we are adding it to list.
}
if(solve(arr)){//if solve returns true we got n
cout<<"Gotcha"<<endl;
reverse(ans.begin(),ans.end()); //we have to reverse it to see the orginal ans
for(string s: ans){
cout<<s<<" ";
}
cout<<endl;
break;
}
bool solve(vector<int>exp){
//cout<<"inside solve"<<endl;
display(exp);
if(exp.size()==0)
return false;
if(foo(exp[0],1,exp)){ //we are always choosing the first number
ans.push_back(to_string(exp[0]));
return true;
}
return false;
}
bool foo(int stk,int index,vector<int>exp){
vectorr;
对于(int j=0;jc您能提供一个输入示例吗?@riccardoperaglia doneyu您可以使用@Darhuuk创建容器的所有置换,但是std::next_permutation
不会考虑重复,并且操作可能是repeated@Norhther但你的问题不是这么说的。你说你的第一本能是相信crea请用尽可能多的信息来展开你的问题。而且,重复排列不会使生成的答案出错,只会使程序变慢。不清楚这是否是一个问题。@n你是否尝试过上述方法来排列n?是否满意你的答案是什么?
#include<iostream>
#include<vector>
#include<string>
#include<bits/stdc++.h>
using namespace std;
vector<int>vec;
vector<char>_oprator;
vector<string>ans;
bool solve(vector<int>);
bool foo(int,int,vector<int>);
void fine(){
cout<<"fine"<<endl;
}
void display(vector<int>vec){
cout<<endl<<"displaying"<<endl;
for(int x: vec)
cout<<x<<" ";
cout<<endl;
cout<<endl;
}
int n;
int main(){
_oprator.push_back('+');
_oprator.push_back('-');
_oprator.push_back('*');
_oprator.push_back('/');
int length;
cin>>length;
cin>>n;
int temp;
for(int i=0;i<length;i++){
cin>>temp;
vec.push_back(temp);
}
display(vec);
int tot=pow(2,length)-1;
for(int i=1;i<=tot;i++){
vector<int>arr;
for(int j=0;j<60;j++){
if(i&(1<<j) && j<vec.size())
arr.push_back(vec[j]);
}
//cout<<"i "<<i<<endl;
//display(arr);
if(solve(arr)){
cout<<"Gotcha"<<endl;
reverse(ans.begin(),ans.end());
for(string s: ans){
cout<<s<<" ";
}
cout<<endl;
break;
}
arr.clear();
}
return 0;
}
bool solve(vector<int>exp){
//cout<<"inside solve"<<endl;
display(exp);
if(exp.size()==0)
return false;
if(foo(exp[0],1,exp)){
ans.push_back(to_string(exp[0]));
return true;
}
return false;
}
bool foo(int stk,int index,vector<int>exp){
//cout<<"ïnside foo"<<endl;
//cout<<"index "<<index<<endl;
//cout<<"stk "<<stk<<endl;
if(index>=exp.size()){
return stk==n;
}
for(int i=0;i<_oprator.size();i++){
if(_oprator[i]=='+'){
if(foo(stk+exp[index],index+1,exp)){
ans.push_back(to_string(exp[index]));
ans.push_back("+");
return true;
}
}
else
if(_oprator[i]=='-'){
if(foo(stk-exp[index],index+1,exp)){
ans.push_back(to_string(exp[index]));
ans.push_back("-");
return true;
}
}
else
if(_oprator[i]=='*'){
if(foo(stk*exp[index],index+1,exp)){
ans.push_back(to_string(exp[index]));
ans.push_back("*");
return true;
}
}
else
if(_oprator[i]=='/'){
if(foo(stk/exp[index],index+1,exp)){
ans.push_back(to_string(exp[index]));
ans.push_back("/");
return true;
}
}
}
return false;
}
int tot=pow(2,length)-1;
vector<int>arr;
for(int j=0;j<60;j++){
if(i&(1<<j) && j<vec.size()) //checking if particular bit is set.
arr.push_back(vec[j]); //if its set we are adding it to list.
}
if(solve(arr)){//if solve returns true we got n
cout<<"Gotcha"<<endl;
reverse(ans.begin(),ans.end()); //we have to reverse it to see the orginal ans
for(string s: ans){
cout<<s<<" ";
}
cout<<endl;
break;
}
bool solve(vector<int>exp){
//cout<<"inside solve"<<endl;
display(exp);
if(exp.size()==0)
return false;
if(foo(exp[0],1,exp)){ //we are always choosing the first number
ans.push_back(to_string(exp[0]));
return true;
}
return false;
}
bool foo(int stk,int index,vector<int>exp){