100分算法悬赏
求表达式[nnn]-[AAA]……的穷举算法。
说明:
1、nnn表示三个数字的组合,AAA表示三个大写字母的组合;
2、要求状态能够保留,不是直接输出就OK了,需要调用一次得到一个值,直到组合完为止;、
举例:
[n]-[A] 的组合为:
0-A、0-B、0-C、…0-Z,
1-A、1-B、1-C、…1-Z,
2-A、2-B、2-C、…2-Z,
………………
9-A、9-B、9-C、…9-Z。
JAVA和C++都可以。
[解决办法]
套四层循环不就完了……
[解决办法]
要不6层
[解决办法]
如果是按顺序输出的话,就好办了。
[解决办法]
第一次,所有的数字设为 "0 ",所有的字母设为 "A "
第二次及以后,将第一位加1,如果等于 ": "(也就是 "9 "+1),或者等于 "[ " (也就是 "Z "+1),重置该位,下一位加1,并判断是否超界.....依此类推, 这个加1取得下一个值的动作可以用递归实现
当最后一位都超界的时候,就是所有值都输出完了。
[解决办法]
这样说能理解吗:
[nnn]-[AAA]
将[nnn]与直角坐标系的横轴相联系;将[AAA]与直角坐标系的纵轴相联系;
一个坐标就是一个组合;
[0,0]-[1,0]-[0,1]-[0,2]-[1,1]-[2,0]-[3,0]-。。。。
从原点出发斜线路径,走过所有坐标。
[解决办法]
上面是二维情况,三维、多维相似。按照x1+x2+x3+...+xn=c,c递增来进行。
[解决办法]
标题含糊不明
[解决办法]
题目是没说清楚[nnn]-[AAA]到底是怎么组合的;
至于要保存状态,你可以用一个静态变量或者一个全局变量,用来保存之前的组合是哪一个就可以了;下一个组合可以按照你自己定义的规则根据上一个组合来产生
[解决办法]
是不是想要这种效果:
#include <iostream>
using namespace std;
void go(int k,int n,int c){
static int *x;
if(k==0){
x=new int[n];
}else if(k==n && c==0){
cout < < "[ " < <x[0];
for(int i=1;i <n;++i){
cout < < ', ' < <x[i];
}
cout < < "]- ";
return;
}else if(c <0 || k> =n){
return;
}
for(int i=0;i <=c;++i){
x[k]=i;
go(k+1,n,c-i);
}
if(k==0){
delete []x;
}
}
int main()
{
int n;
cout < < "输入一个数: ";
cin> > n;
for(int c=0;c <10;++c){
go(0,n,c);
}
return 0;
}
输入一个数:3
[0,0,0]-[0,0,1]-[0,1,0]-[1,0,0]-[0,0,2]-[0,1,1]-[0,2,0]-[1,0,1]-[1,1,0]-[2,0,0]-
[0,0,3]-[0,1,2]-[0,2,1]-[0,3,0]-[1,0,2]-[1,1,1]-[1,2,0]-[2,0,1]-[2,1,0]-[3,0,0]-
[0,0,4]-[0,1,3]-[0,2,2]-[0,3,1]-[0,4,0]-[1,0,3]-[1,1,2]-[1,2,1]-[1,3,0]-[2,0,2]-
[2,1,1]-[2,2,0]-[3,0,1]-[3,1,0]-[4,0,0]-[0,0,5]-[0,1,4]-[0,2,3]-[0,3,2]-[0,4,1]-
[0,5,0]-[1,0,4]-[1,1,3]-[1,2,2]-[1,3,1]-[1,4,0]-[2,0,3]-[2,1,2]-[2,2,1]-[2,3,0]-
[3,0,2]-[3,1,1]-[3,2,0]-[4,0,1]-[4,1,0]-[5,0,0]-[0,0,6]-[0,1,5]-[0,2,4]-[0,3,3]-
[0,4,2]-[0,5,1]-[0,6,0]-[1,0,5]-[1,1,4]-[1,2,3]-[1,3,2]-[1,4,1]-[1,5,0]-[2,0,4]-
[2,1,3]-[2,2,2]-[2,3,1]-[2,4,0]-[3,0,3]-[3,1,2]-[3,2,1]-[3,3,0]-[4,0,2]-[4,1,1]-
[4,2,0]-[5,0,1]-[5,1,0]-[6,0,0]-[0,0,7]-[0,1,6]-[0,2,5]-[0,3,4]-[0,4,3]-[0,5,2]-
[0,6,1]-[0,7,0]-[1,0,6]-[1,1,5]-[1,2,4]-[1,3,3]-[1,4,2]-[1,5,1]-[1,6,0]-[2,0,5]-
[2,1,4]-[2,2,3]-[2,3,2]-[2,4,1]-[2,5,0]-[3,0,4]-[3,1,3]-[3,2,2]-[3,3,1]-[3,4,0]-
[4,0,3]-[4,1,2]-[4,2,1]-[4,3,0]-[5,0,2]-[5,1,1]-[5,2,0]-[6,0,1]-[6,1,0]-[7,0,0]-
[0,0,8]-[0,1,7]-[0,2,6]-[0,3,5]-[0,4,4]-[0,5,3]-[0,6,2]-[0,7,1]-[0,8,0]-[1,0,7]-
[1,1,6]-[1,2,5]-[1,3,4]-[1,4,3]-[1,5,2]-[1,6,1]-[1,7,0]-[2,0,6]-[2,1,5]-[2,2,4]-
[2,3,3]-[2,4,2]-[2,5,1]-[2,6,0]-[3,0,5]-[3,1,4]-[3,2,3]-[3,3,2]-[3,4,1]-[3,5,0]-
[4,0,4]-[4,1,3]-[4,2,2]-[4,3,1]-[4,4,0]-[5,0,3]-[5,1,2]-[5,2,1]-[5,3,0]-[6,0,2]-
[6,1,1]-[6,2,0]-[7,0,1]-[7,1,0]-[8,0,0]-[0,0,9]-[0,1,8]-[0,2,7]-[0,3,6]-[0,4,5]-
[0,5,4]-[0,6,3]-[0,7,2]-[0,8,1]-[0,9,0]-[1,0,8]-[1,1,7]-[1,2,6]-[1,3,5]-[1,4,4]-
[1,5,3]-[1,6,2]-[1,7,1]-[1,8,0]-[2,0,7]-[2,1,6]-[2,2,5]-[2,3,4]-[2,4,3]-[2,5,2]-
[2,6,1]-[2,7,0]-[3,0,6]-[3,1,5]-[3,2,4]-[3,3,3]-[3,4,2]-[3,5,1]-[3,6,0]-[4,0,5]-
[4,1,4]-[4,2,3]-[4,3,2]-[4,4,1]-[4,5,0]-[5,0,4]-[5,1,3]-[5,2,2]-[5,3,1]-[5,4,0]-
[6,0,3]-[6,1,2]-[6,2,1]-[6,3,0]-[7,0,2]-[7,1,1]-[7,2,0]-[8,0,1]-[8,1,0]-[9,0,0]-
[解决办法]
/**
*迭代给出所有表达式,需要JRE1.5或更高
*@author : Eastsun <http://eastsun.javaeye.com>
*@version: 1.0 2007/5/14
*/
import java.util.*;
public class ListExp{
public static void main(String[] args){
ExprIter ei =new ExprIter(new String[]{ "123 ", "ABC ", "XYZ ", "UVW "});
//把上面改成 new ExprIter(new String[]{ "0123456789 ", "ABCDEFGHIJKMNLOPQRSTUVWXYZ "});就是楼主那个了
Iterator <String> iter =ei.iterator();
int count =0;
while(iter.hasNext()){
count++;
System.out.print(iter.next()+ " , ");
if(count%10==0) System.out.println();
}
}
}
class ExprIter implements Iterable <String> {
private String[] strs;
private int[] lens;
public ExprIter(String[] strs){
this.strs =new String[strs.length];
this.lens =new int[strs.length];
for(int index=0;index <strs.length;index++){
this.strs[index] =strs[index];
this.lens[index] =strs[index].length();
}
}
public Iterator <String> iterator(){
return new ExprIterator();
}
private class ExprIterator implements Iterator <String> {
private int[] counts =new int[strs.length];
private boolean end =false;
public boolean hasNext(){
return (!end);
}
public String next(){
if(end) throw new NoSuchElementException();
StringBuilder sb =new StringBuilder(2*strs.length-1);
sb.append(strs[0].charAt(counts[0]));
for(int index=1;index <strs.length;index++){
sb.append( '- ');
sb.append(strs[index].charAt(counts[index]));
}
int index =strs.length-1;
while(index> =0){
counts[index]++;
if(counts[index]> =lens[index]){
counts[index] =0;
index --;
}
else break;
}
if(index <0) end =true;
return sb.toString();
}
public void remove(){
throw new UnsupportedOperationException();
}
}
}
运行的结果:
1-A-X-U ,1-A-X-V ,1-A-X-W ,1-A-Y-U ,1-A-Y-V ,1-A-Y-W ,1-A-Z-U ,1-A-Z-V ,1-A-Z-W ,1-B-X-U ,
1-B-X-V ,1-B-X-W ,1-B-Y-U ,1-B-Y-V ,1-B-Y-W ,1-B-Z-U ,1-B-Z-V ,1-B-Z-W ,1-C-X-U ,1-C-X-V ,
1-C-X-W ,1-C-Y-U ,1-C-Y-V ,1-C-Y-W ,1-C-Z-U ,1-C-Z-V ,1-C-Z-W ,2-A-X-U ,2-A-X-V ,2-A-X-W ,
2-A-Y-U ,2-A-Y-V ,2-A-Y-W ,2-A-Z-U ,2-A-Z-V ,2-A-Z-W ,2-B-X-U ,2-B-X-V ,2-B-X-W ,2-B-Y-U ,
2-B-Y-V ,2-B-Y-W ,2-B-Z-U ,2-B-Z-V ,2-B-Z-W ,2-C-X-U ,2-C-X-V ,2-C-X-W ,2-C-Y-U ,2-C-Y-V ,
2-C-Y-W ,2-C-Z-U ,2-C-Z-V ,2-C-Z-W ,3-A-X-U ,3-A-X-V ,3-A-X-W ,3-A-Y-U ,3-A-Y-V ,3-A-Y-W ,
3-A-Z-U ,3-A-Z-V ,3-A-Z-W ,3-B-X-U ,3-B-X-V ,3-B-X-W ,3-B-Y-U ,3-B-Y-V ,3-B-Y-W ,3-B-Z-U ,
3-B-Z-V ,3-B-Z-W ,3-C-X-U ,3-C-X-V ,3-C-X-W ,3-C-Y-U ,3-C-Y-V ,3-C-Y-W ,3-C-Z-U ,3-C-Z-V ,
3-C-Z-W ,
[解决办法]
class Bit {//表示一个位的类
int weight;//权值
int value;//值
boolean addOne();//为这个位加1。如果超过权值产生进位则返回true
char toChar();//输出此位
}
class NumberBit extends Bit{
weight=10;
}
class CharBit extends Bit{
weight=26;
}
class StrangeNumber{//奇怪的数字类
List <Bit> [] number=new List <Bit> [len];//维护一个数组或者list,表示len个位组成的数字
void addOne();//最低位加一操作,递归处理进位。想办法处理下溢出问题即可。
String toString();//输出
}
主程序中产生一个StrangeNumber对象,自己会保持状态的。需要的时候加1,输出。
[解决办法]
补充,[nnn]-[AAA]格式的数字中每一个[]为一位。其中NumberBit和CharBit只是此位进制为[n]或者[A]时候适合的类。如果是[nnn]形式的类,采用不同的权值,注意输出格式即可。
[解决办法]
10进制和26进制~
[解决办法]
十进制的直接使用变量就行
9-》009
11-》011
英文字母26个
25-> 0,0,25-> AAZ
27-> 0,1,1-> ABB
677-> 1,0,1-> BAB
具体代码自己写吧
[解决办法]
mark
[解决办法]
C的语法忘的差不多了 如果你能看懂VB的就给你写个
[解决办法]
to sailing27(许愿) :
我那个不可以吗?为什么你要重写呢.
[解决办法]
to sailing27(许愿) :
我的已经考虑到重用的问题了丫,否则就不用写那么多代码鸟~
[解决办法]
问题不很清楚?
到底是用固定的三个数字(从000到999),
还是1-3个数字(从0,1,..9,直到...997,998,999)?
[解决办法]
还有,在nnn中,是否允许三个n相同?
[解决办法]
题目不清楚 把题目说清楚点
[解决办法]
题目很简单可惜我只会VB~
[解决办法]
flyingghost(游魂) 正解
[解决办法]
仍然是 flyingghost(游魂) 正解 ^_^
他才是真正掌握了面向对象的高人,偶来解释下他的思路吧:
如果你需要全部的2位10进制整数,怎样写最简单?
for(int i=0;i <100;i++) printf( "%2d ",i);
哦,不过是个2位10进制计数器罢了。
如果换成16进制呢?48进制?56进制?
很简单,n进制计数器的实现就是:最低位++;如果最低位等于n,则次低位++……依次类推
换个BT点的:假设算工时,一年=12月;一月=4周;一周=7天;1天=8小时,怎么算?
年月周日时,其中时为8进制,逢8日加一;日为7进制,逢7周加一;周为4进制,逢4月加一……
明白了吧?用flyingghost(游魂)的位类,为时生成8进对象,为日生成7进对象……
然后,当时满8绕回0时,通知日对象加一;当日对象满7时,通知周对象加一……
至于[nnn]-[AAA],则不过是 10进对象 <-10进对象 <-10进对象 <-26进对象 <-26进对象 <-26进对象 的一个“超级计数器”罢了
如果你需要nnn不重复,AAA不重复,简单,扫描全部6位,有重复的就继续+1即可。
20行代码,解决一切相关问题。何须动辄成百上千行代码?
程序,是要用脑子来写的^_^
[解决办法]
对于全组合,而且多列同量的全组合,即楼主提到的[nnn...][AAA...][BBB...]...,其中[nnn...],[AAA...]等等中间的元素个数相同,而且不存在重复,元素组内部可以按规则顺序化,则有一个最简单的输出全组合的方法,那就是数制转换法,你先确定输出的可能数,比如每组元素中的个数是3,有两组,则共有3×3×3=27种可能,从0开始计数到 <27的最大整数,并转换成3进制数,按元素组数进行3进制数标准格式化,顶部补0,则这个数的每位可以看作原始元素组的对应顺序数,比如000,表示这样的组合n0A0B0,以此类推,这样计一次数就可以完成全组合输出。
[解决办法]
其实这个算法还可以扩展到元素组元素个数不相等情况。