c++求若干个集合的笛卡尔积
来源:互联网 发布:linux gre over ipsec 编辑:程序博客网 时间:2024/05/19 11:47
大家都知道求任意两个集合的笛卡尔积一般是如下这种方式
#include <stdio.h>#define m 3#define n 2int main() { int i,j; char a[m],b[n]; for (i=0;i<m;i++) scanf("%c",&a[i]); getchar();//吃掉\n for (j=0;j<n;j++) scanf("%c",&b[j]); printf("集合a:\n"); for (i=0;i<m;i++) printf("%c\t",a[i]); printf("\n集合b:\n"); for (j=0;j<n;j++) printf("%c\t",b[j]); printf("\n{"); for (i=0;i<m;i++) for (j=0;j<n;j++) printf("<%c,%c> ",a[i],b[j]); printf("}\n"); return 0;}
例如输入两个集合“ABC”和“12”,结果如下
但是对于一个复杂字符串来说,例如"[A|B|C] D [E|F|G] [M|N]"
(“[A|B|C]”代表一个集合,其他类是,集合中的元素用“|”隔开)这种形式的该怎么处理呢?
第一步,熟悉python的同学第一反应当然是利用split方法来处理喽,但是c++中没有split方法,但是提供了strtok函数来处理,方法如下
//分割字符串,spl代表分割规则int StrSplit(char dst[][80], char* str, const char* spl){ int n = 0; char *result = NULL; result = strtok(str, spl); while (result != NULL) { strcpy(dst[n++], result); result = strtok(NULL, spl); } return n; //返回分割集合的个数}
具体调用如下
StrSplit(dst, StrToChArr(m), " ");//以空格分割
接下来,最关键的方法就是求笛卡尔积了,我们使用STL中的vector来处理,方法如下
//求若干集合的笛卡尔积string decare(const vector<vector<string>> &sets, string add){ vector<vector<string>> rs; int n = sets.size(); vector<string> tmp; string word, result; for (int i = 0; i < n; ++i) { tmp.push_back(sets[i][0]); } rs.push_back(tmp); for (int i = n - 1; i >= 0; --i) { int nRsSize = rs.size(); for ( int k = 1; k < sets[i].size(); ++k) { for ( int j = 0; j < nRsSize; ++j) { tmp = rs[j]; tmp[i] = sets[i][k]; rs.push_back(tmp); } } } for (vector<vector<string> >::iterator iter = rs.begin(); iter != rs.end(); iter++) { word += add; for ( int i = 0; i < (*iter).size(); i++) { word += (*iter)[i] + " ";//词之间添加空格 } if (iter != rs.end() - 1) { word += "\n";//末尾不需要换行 } else { word += ""; } } return word;}
完整程序如下
#include"stdafx.h"#include "fstream"#include "vector"#include "string"#include "algorithm"#include "regex"#include "iterator"#include "iostream"#include "windows.h"#include "wchar.h"#include "io.h"#include "stdlib.h"#include "vector"#include "set"//#define TXT_NAME "word.xml"//保存合并后的xml结果using namespace std;//utf8转stringstd::string UTF8_To_string(const std::string & str){ int nwLen = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, NULL, 0); wchar_t * pwBuf = new wchar_t[nwLen + 1]; memset(pwBuf, 0, nwLen * 2 + 2); MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.length(), pwBuf, nwLen); int nLen = WideCharToMultiByte(CP_ACP, 0, pwBuf, -1, NULL, NULL, NULL, NULL); char * pBuf = new char[nLen + 1]; memset(pBuf, 0, nLen + 1); WideCharToMultiByte(CP_ACP, 0, pwBuf, nwLen, pBuf, nLen, NULL, NULL); std::string retStr = pBuf; delete[]pBuf; delete[]pwBuf; pBuf = NULL; pwBuf = NULL; return retStr;}//分隔字符串int StrSplit(char dst[][80], char* str, const char* spl){ int n = 0; char *result = NULL; result = strtok(str, spl); while (result != NULL) { strcpy(dst[n++], result); result = strtok(NULL, spl); } return n;}//判断是否需要做分隔处理bool IncludeCh(char str[], char ch) { int i; bool has = false; for (i = 0; str[i]; ++i) { if (str[i] == ch) return true; } return false;}//string转化成char数组char* StrToChArr(string src){ char *dst = new char[255]; int i; for (i = 0; i < src.length(); i++) dst[i] = src[i]; dst[i] = '\0'; return dst;}//求若干集合的笛卡尔积string decare(const vector<vector<string>> &sets, string add){ vector<vector<string>> rs; int n = sets.size(); vector<string> tmp; string word, result; for (int i = 0; i < n; ++i) { tmp.push_back(sets[i][0]); } rs.push_back(tmp); for (int i = n - 1; i >= 0; --i) { int nRsSize = rs.size(); for (int k = 1; k < sets[i].size(); ++k) { for (int j = 0; j < nRsSize; ++j) { tmp = rs[j]; tmp[i] = sets[i][k]; rs.push_back(tmp); } } } for (vector<vector<string> >::iterator iter = rs.begin(); iter != rs.end(); iter++) { word += add; for (int i = 0; i < (*iter).size(); i++) { word += (*iter)[i] + " ";//词之间添加空格 } if (iter != rs.end() - 1) { word += "\n";//末尾不需要换行 } else { word += ""; } } return word;}//输出笛卡尔积结果保存到文件, add为扩充词string Descarte(string m, string add){ vector<vector<string>> charSet; vector<string> tmp[100]; char dst[10][80]; int k = StrSplit(dst, StrToChArr(m), " ");//第一次分隔,得到 "[A|B|C]"、"D" 、"[E|F|G]""[M|N]"4组数据 char dsts[10][80]; for (int m = 0; m < k; m++) { int u = StrSplit(dsts, dst[m], "|[]");//第二次分隔,得到每组数据中的具体值,例如"[A|B|C]"中的"A"、"B"、"C" for (int f = 0; f < u; f++) { tmp[m].push_back(dsts[f]); } charSet.push_back(tmp[m]); } return decare(charSet, add);}int main() { string m = "[A|B|C] D [E|F|G] [M|N]"; if (IncludeCh(StrToChArr(m), '[') && IncludeCh(StrToChArr(m), ']')) { cout << Descarte(m, "") << endl; } system("pause"); return 0;}
如果您使用VS,在编译时往往会出现以下错误
This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
原因是Visual C++ 2012 以上版本使用了更加安全的 run-time library routines 。新的Security CRT functions(就是那些带有“_s”后缀的函数)
解决办法是即在预编译头文件 stdafx.h 里加入下面两句:
#define _CRT_SECURE_NO_DEPRECATE#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1
注意这两句话的位置要在没有include任何头文件之前
修改后的完整stdafx.h如下
// stdafx.h : 标准系统包含文件的包含文件,// 或是经常使用但不常更改的// 特定于项目的包含文件//#pragma once//消除his function or variable may be unsafe警告#define _CRT_SECURE_NO_DEPRECATE#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1#include "targetver.h"#include <stdio.h>#include <tchar.h>// TODO: 在此处引用程序需要的其他头文件
接下来看下运行结果
换一个简单一点的字符串,比如“[A|B] [C|D]”(注意集合直接要有空格)
结果如下,ok
0 0
- c++求若干个集合的笛卡尔积
- php 计算多个集合的笛卡尔积
- php 计算多个集合的笛卡尔积
- php 计算多个集合的笛卡尔积
- 排列组合 包含求集合笛卡尔积
- 多个集合积-笛卡尔积
- 多个集合做笛卡尔积
- 求笛卡尔积的php代码
- 求若干个整数的平均数
- 求笛卡尔积
- Python求笛卡尔积
- 多数组求笛卡尔积
- 把正整数n表示成若干个不同的正整数的和,求积的最大值
- 数据结构和算法数组系列---求数组的笛卡尔积
- 把正整数n表示成若干个正整数的和,求积的最大值
- Python2.7实现笛卡尔积N个数组的排列组合
- 求m个元素集合中n个元素的所有子集(C/OC)
- javascript 求json对象的笛卡尔乘积
- react-native-art-绘图入门
- async和await 用法
- c的学习之路(1)
- 【软考学习】——软件过程模型
- hdu 1253
- c++求若干个集合的笛卡尔积
- 二分题目最全总结(持续更新)
- resource deadlock would occur
- Java初级程序员到CTO的技术路线图
- 如何定义BaseActivity与设定TitleBar
- 10.31
- 读取layout属性-AttributeSet TypedArray
- C#快速写延迟函数
- Java设计模式之——状态模式