文档章节

用tinyscript解一些典型算法题,小试牛刀

悠悠然然
 悠悠然然
发布于 2017/08/11 12:51
字数 2746
阅读 1475
收藏 42

问题1:用1、2、2、3、4、5这六个数字,打印出所有不同的排列,如:512234、412345等,要求:"4"不能在第三位,"3"与"5"不能相连。

原题链接:http://blog.csdn.net/zhutulang/article/details/7775644

tinyscript解法

numbers=[1,2,2,3,4,5];
numbers.permuteAll((e) -> {
	if(e[3]!=4&&!(abs(e.indexOf(3)-e.indexOf(5))==1)){
		println(e);
	}
});

运行结果,篇幅原因只贴部分:

[1, 2, 2, 3, 4, 5]
[1, 2, 2, 5, 4, 3]
[1, 2, 3, 2, 4, 5]
[1, 2, 3, 2, 5, 4]
[1, 2, 3, 4, 2, 5]
[1, 2, 3, 4, 5, 2]
[1, 2, 5, 4, 3, 2]
[1, 2, 5, 4, 2, 3]
[1, 2, 5, 2, 4, 3]
[1, 2, 5, 2, 3, 4]
[1, 2, 2, 3, 4, 5]
[1, 2, 2, 5, 4, 3]
[1, 2, 3, 2, 4, 5]
[1, 2, 3, 2, 5, 4]
[1, 2, 3, 4, 2, 5]
[1, 2, 3, 4, 5, 2]
[1, 2, 5, 4, 3, 2]
[1, 2, 5, 4, 2, 3]

Java解法:

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.TreeSet;

public class Sort {

	static TreeSet<String> ts=new TreeSet<String>();
	
	public static void main(String[] args) {
		 
		 String[] d={"1","2","2","3","4","5"};
		 List<String> s=new ArrayList<String>();
		 StringBuilder rs=new StringBuilder();
		 for(int i=0;i<d.length;i++)
			 s.add(d[i]);

		pl(s, rs);
		
		Iterator<String> iterator=ts.iterator();
		while (iterator.hasNext()) 
               System.out.println(iterator.next());
		
		
		 System.out.println("总数是:"+ts.size());
		 
		 
	}
	
	//全排列
	public static void pl(List<String> s,StringBuilder rs){
		
	    
		if(s.size()==1){
			
			rs.append(s.get(0));
			if(rs.indexOf("4")!=2
		             && (!rs.toString().contains("35")&& !rs.toString().contains("53"))  )
		         {
				
				ts.add(rs.toString());
				
			}
			//if(rs.length()>0)
			   rs.delete(rs.length()-1, rs.length());
			    			
		}else{
			
			
			for(int i=0;i<s.size();i++)
			{
				
				rs.append(s.get(i));
				List<String> tmp=new ArrayList<String>();  
				for(String a:s)  
				     tmp.add(a);  
				

				tmp.remove(i);
				pl(tmp, rs);
				//if(rs.length()>0)
				   rs.delete(rs.length()-1, rs.length());  
							 
			}							
		}		
	}
}

问题2:abc+def=ghi,以上字母为1-9的数字,且两两不相同,求可能的组合。

原题链接:

tinyscript解法

/**
abc+def=ghi,以上字母为1-9的数字,且两两不相同。
*/

numbers=[1 .. 9];
numbers.permuteAll((e) -> {
	if(e[1]*100+e[2]*10+e[3]+e[4]*100+e[5]*10+e[6]==e[7]*100+e[8]*10+e[9]){
		println(e);
	}
});

运行结果,篇幅原因只贴部分:

[1, 2, 4, 6, 5, 9, 7, 8, 3]
[1, 2, 5, 7, 3, 9, 8, 6, 4]
[1, 2, 7, 3, 5, 9, 4, 8, 6]
[1, 2, 7, 3, 6, 8, 4, 9, 5]
[1, 2, 8, 4, 3, 9, 5, 6, 7]
[1, 2, 8, 3, 6, 7, 4, 9, 5]
[1, 2, 9, 4, 3, 8, 5, 6, 7]
[1, 2, 9, 6, 5, 4, 7, 8, 3]
[1, 2, 9, 7, 3, 5, 8, 6, 4]
[1, 2, 9, 3, 5, 7, 4, 8, 6]
[1, 3, 4, 6, 5, 8, 7, 9, 2]
[1, 3, 5, 7, 2, 9, 8, 6, 4]
[1, 3, 8, 4, 2, 9, 5, 6, 7]
[1, 3, 8, 6, 5, 4, 7, 9, 2]
[1, 3, 9, 4, 2, 8, 5, 6, 7]

C解法

#include <stdio.h>
void main()
{
        int count=0,sum=0,num1,num2,a,b,c,d,e,f;
        
        for(a=1;a<=9;a++)
            for(b=0;b<=9;b++)
            {
                if(a==b)
                    continue;
                for(c=1;c<=9;c++)
                {
                    if(a==c||b==c)
                        continue;
                        //**********************
                        num1=a*100+b*10+c;
                        for(d=1;d<=9;d++)
                        {
                           if(d==a||d==b||d==c)
                                continue;
                                 //printf("good1 \n");
                            for(e=0;e<=9;e++)
                            {
                                if(d==e||e==a||e==b||e==c)
                                    continue;
                                for(f=1;f<=9;f++)
                                {
                                    if(d==f||e==f||f==a||f==b||f==c)
                                        continue; 
                                    num2=d*100+e*10+f;
                                    sum=num1+num2;
                                    
                                    if(sum<=1000||sum%10==a||sum%10==b||sum%10==c||sum%10==d||sum%10==e||sum%10==f
                                    ||(sum/10)%10==a||(sum/10)%10==b||(sum/10)%10==c||(sum/10)%10==d||(sum/10)%10==e||(sum/10)%10==f
                                    ||(sum/100)%10==a||(sum/100)%10==b||(sum/100)%10==c||(sum/100)%10==d||(sum/100)%10==e||(sum/100)%10==f
                                    ||sum/1000==a||sum/1000==b||sum/1000==c||sum/1000==d||sum/1000==e||sum/1000==f
                                    ||sum%10==(sum/10)%10||sum%10==(sum/100)%10||sum%10==sum/1000||(sum/10)%10==(sum/100)%10||(sum/10)%10==sum/1000||(sum/100)%10==sum/1000
                                    )
                                        continue;
                                        count++;
                                        printf("%d + %d = %d \n",num1,num2,sum);
  
                                    
                                }
                            }
                        }

                }
            }
            printf("count=%d\n",count);

}

问题3:马克思手稿中有一道趣味数学题:有30个人,其中有男人、女人和小孩,在一家饭馆里吃饭 共花了50先令, 每个男人各花5先令,每个女人各花2先令,每个小孩各花1先令,问男人、女人和小孩各有几人?

tinysctipt解法

elements = [0 ..30];

elements.permute(3,(e) -> {
	if(sum(e)==30 && e[1]*5+e[2]*2+e[3]==50){
		println(e);
	}
});

运行结果:

[0, 20, 10]
[1, 16, 13]
[2, 12, 16]
[3, 8, 19]
[4, 4, 22]
[5, 0, 25]

Java解法

for(int a=1;a<50/5;a++) {
    for(int b=1;b<50/2;b++) {
    	for(int c=1;c<50/1;c++) {
    		if((a+b+c)==30 && a*5+b*2+c*1==50) {
    			System.out.println("男人:"+a+" 女人:"+b+" 小孩:"+c );
    		}
    	}
    }
}

或者

public static void main(String[] args) {
        for (int a = 1; a <= 5; a++) {
            for (int b = 1; b <= 20; b++) {
                if (4 * a + b == 20) {
                    int c = 30 - a - b;
                    if (c != 0) {
                        System.out.println(a + "--" + b + "--" + c);
                    }
                }
            }
        }
    }

问题4:青年歌手参加歌曲大奖赛,有n(n>2)个评委打分,试编程求选手的平均得分(去掉一个最高分和 一个最低分)

tinyscript解法

score(scores)->{
	return (sum(scores)-max(scores)-min(scores))/(scores.size()-2);
};

println(score(elements));

C解法

#include<stdio.h>  
void main()  
{  
    int sum = 0,i;  
    double avg,b;  
    int a[10];  
    int max,min;  
  
    for(i=0;i<10;i++)  
    {  
        scanf("%d",&a[i]);  
        if(i==0)//只有第一次赋值max=min=a[0]  
        {  
            max = a[0];  
            min = a[0];  
        }  
        if(max<a[i])  
            max = a[i];  
        if(min>a[i])  
            min = a[i];  
  
        sum = sum+a[i];  
    }  
    b = sum-max-min;  
    avg = b/8.0;  
    printf("平均分为:%.2lf\n",avg);//保留两位小数  
}  

背包问题:有编号分别为a,b,c,d,e的五件物品,它们的重量分别是2,2,6,5,4,它们的价值分别是6,3,5,4,6, * 现在给你个承重为10的背包,如何让背包里装入的物品具有最大的价值总和?

tinyscript解法:

/**
 * 有编号分别为a,b,c,d,e的五件物品,它们的重量分别是2,2,6,5,4,它们的价值分别是6,3,5,4,6,
 * 现在给你个承重为10的背包,如何让背包里装入的物品具有最大的价值总和?
 */

class Obj{
	name,weight,value;
	Obj(name,weight,value){
		this.name=name;
		this.weight=weight;
		this.value=value;
	}
}
list=[new Obj("a",2,6),new Obj("b",2,3),new Obj("c",6,5),new Obj("d",5,4),new Obj("e",4,6)];
//上面是初始化数据,下面是解决问题的代码
sum=0;
ele=null;
for(i:[1 ..list.size()]){
	list.combine(i,(e) -> {		
		if(sum(e.weight)<=10&&sum(e.value)>sum){
			ele=e;
			sum=sum(e.value);
		}
	});
}
println(sum);
println(ele);

运行结果:

15
[Obj[name=a,weight=2,value=6], Obj[name=b,weight=2,value=3], Obj[name=e,weight=4,value=6]]

上面是穷举法速度非常慢,但是可以求出最优解;下面是次优解写法,性能有非常大的提高,但是有可能不是最优解。

/**
 * 有编号分别为a,b,c,d,e的五件物品,它们的重量分别是2,2,6,5,4,它们的价值分别是6,3,5,4,6,
 * 现在给你个承重为10的背包,如何让背包里装入的物品具有最大的价值总和?
 */

class Obj{
	name,weight,value;
	Obj(name,weight,value){
		this.name=name;
		this.weight=weight;
		this.value=value;
	}
}
list=[new Obj("a",2,6.0),new Obj("b",2,3.0),new Obj("c",6,5.0),new Obj("d",5,4.0),new Obj("e",4,6.0)];
//上面是初始化数据,下面是解决问题的代码
sum=0;
list.sort((l,r)->{return (r.value/r.weight).compareTo(l.value/l.weight);});
result=[];
for(i:[1 ..list.size()]){
	if(sum+list[i].weight<=10){
		sum+=list[i].weight;
		result.add(list[i]);
	}
}
println(sum);
println(result);

java代码:

  public void bag(int[] weights, int[] values, int bagsize){  
int[][] result = new int[weights.length][bagsize+1];  
for(int i=0;i<bagsize+1;i++){  
    for(int j=0;j<weights.length;j++){  
        if(i==0){  
            result[j][i] = 0;  
            System.out.print(result[j][i]+" ");  
            continue;  
        }else if(j==0){  
            if(weights[j]<=i){  
                result[j][i] = values[j];  
            }else{  
                result[j][i] = 0;     
            }  
        }else{  
            if(weights[j]<=i){  
                result[j][i] = result[j-1][i-weights[j]]+values[j]>result[j-1][i]?result[j-1][i-weights[j]]+values[j]:result[j-1][i];  
            }else{  
                result[j][i] = result[j-1][i];  
            }  
        }  
    }  
}  
for(int m=0;m<weights.length;m++){  
    for(int n=0;n<bagsize+1;n++){  
        System.out.print(result[m][n]+" ");  
    }  
    System.out.println("");  
  
}  

问题5:基金量化投资:选择一个月收益排名前50名,并且最大回撤率小于50%,并且基金经理任职连续超过一年,管理的基金在同类基金排名前20%,列出符合条件的基金。

可能有的同学说,你这个也就做做算法穷举类题目不错别的又干不了什么,说的非常不错,接下来展示一个实际业务。

由于篇幅原件,数据只提供部分表达意思即可:

基金数据

code1	name	date	value
003860	招商招旭纯债C	2017/7/1	1.188147057
160630	鹏华国防	2017/7/1	1.58792832
160643	鹏华中证	2017/7/1	0.922133108
001838	国投瑞银	2017/7/1	1.537061604
630011	华商主题精选	2017/7/1	1.443479085
003860	招商招旭纯债C	2017/7/2	1.044532467
160630	鹏华国防	2017/7/2	1.438359583
160643	鹏华中证	2017/7/2	0.894619462
001838	国投瑞银	2017/7/2	1.734040948
630011	华商主题精选	2017/7/2	1.000473053
003860	招商招旭纯债C	2017/7/3	1.717215024
160630	鹏华国防	2017/7/3	1.780652734
160643	鹏华中证	2017/7/3	1.686924083

基金经理积分数据

code3	manager3	type	repay	avg	rank
003860	王平	混合型	10.17%	3.98%	30%
160630	蒋秋洁	混合型	23.10%	3.98%	15%
160643	李佳亮	固定收益	1.35%	-3.17%	13%
001838	陈剑波	分级杠杆	-17.23%	-3.17%	80%
630011	王平	股票型	154.65%	20.92%	0%
161724	蒋秋洁	混合型	18.32%	4.08%	15%
168204	李佳亮	股票型	4.41%	4.55%	50%
002779	陈剑波	固定收益	42.68%	4.55%	1%
161032	王平	分级杠杆	4.41%	7.96%	75%
161725	李佳亮	股票型	25.27%	7.96%	18%

基金经理与基金管理关系数据

code2	firstdt	lastdt	manager2
003860	2006	2007	蒋秋洁
160630	2005	2008	李佳亮
160643	2005	2006	陈剑波
001838	2006	2010	王平
630011	2005	2006	蒋秋洁
003860	2007	2010	李佳亮
160630	2008	2009	陈剑波
160643	2006	2007	王平
001838	2010	2013	蒋秋洁
630011	2006	2009	李佳亮
003860	2010	2012	陈剑波
160630	2009	2013	王平
160643	2007	2013	蒋秋洁
001838	2013	2014	李佳亮
630011	2009	2010	陈剑波
003860	2012	2017	王平
160630	2015	2017	蒋秋洁
160643	2014	2017	李佳亮
001838	2014	2017	陈剑波
630011	2010	2017	王平
161724	2006	2007	蒋秋洁
168204	2005	2008	李佳亮
002779	2005	2006	陈剑波
161032	2006	2010	王平
161725	2005	2006	蒋秋洁
161724	2007	2010	李佳亮
168204	2008	2009	陈剑波
002779	2006	2007	王平
161032	2010	2013	蒋秋洁

tinyscript解法:

/*
   基金量化投资:选择一个月收益排名前50名,并且最大回撤率小于50%,并且基金经理任职连续超过一年,管理的基金在同类基金排名前20%,列出符合条件的基金。
*/

dataset = readTxt("/example/dayinfo.txt");
groupds =dataset.insertColumn(3,"UP").insertColumn(4,"rate").convert("value","double").group("code1");
groupds.update("UP",(e)->{
	last = 31-e;
	first = 1-e;
	return (value[last]-value[first])/value[first];
});//求一月的净值

groupds.update("rate",(e)->{
	minvalue = value[0];	
	for(i = 1;i<=31-e;i++){
		if(value[i]<minvalue){
			minvalue = value[i];//对每一个值求在之后的最小净值
		}
	}
	return (value[0]-minvalue)/value[0];
});

groupds.update("rate",(e)->{
	last = 31-e;
	first = 1-e;
	maxvalue = 0;
	for(i = first;i<=last;i++){
		maxvalue = max(maxvalue,rate[i]);
		
	}
	
	return maxvalue;
});//对每一个净值的回撤率进行比较求出最大回撤率

//过滤回撤率大于50%的数据
groupds = groupds.sort("UP desc");
groupds = groupds.limit(1,5);

groupds = groupds.filterGroup(rate[0]<=0.5);

dataset2 = readTxt("/example/history.txt");
dataset3 = readTxt("/example/score.txt");
result = dataset2.match(dataset3,code3==code2&&manager3==manager2);
result = result.convert("lastdt","int").convert("firstdt","int").convert("rank","double").filter(lastdt==2017&&lastdt-firstdt>=3).filter(rank<=0.2);
result = result.match(groupds,code3==code1);

for(i = 1;i<=result.getRows();i++){
	println("符合条件的基金代码:"+result[i][1]);
}

运行结果:

符合条件的基金代码:160643
符合条件的基金代码:630011
符合条件的基金代码:161724

java解法:

用Java写,不仅仅是烧脑,长度比上面所有的长度都长......

总结

以上只是tinyscript脚本的简单展示,还有很多很多特性没有展示,比如数据库开发相关有比较大的突破,敬请期待下次分享。

喜欢我博客的同学请关注我,以便第一时间接受到相关信息推送。

© 著作权归作者所有

共有 人打赏支持
悠悠然然

悠悠然然

粉丝 2398
博文 184
码字总数 360373
作品 14
杭州
架构师
私信 提问
加载中

评论(13)

墨径_猿猴
不明白有什么可比性?
Kuangcp
Kuangcp

引用来自“悠悠然然”的评论

引用来自“Kuangcp”的评论

总感觉你JAVA故意写那么长…明明用更少的代码可以实现。而且JAVA的繁杂是事实,这样的比较并没有意义~和同类比倒还行,Python groovy什么的

回复@Kuangcp : 那个不是我写的,因此没有故意不故意一说。那个是从百度搜出来的。

悠悠然然
悠悠然然

引用来自“久永”的评论

对比起,我这搞了十几年C#的看不懂你文章里面的C#代码,你确定是C#?
已经纠正
悠悠然然
悠悠然然

引用来自“久永”的评论

对比起,我这搞了十几年C#的看不懂你文章里面的C#代码,你确定是C#?
确实笔误,是C
久永
久永
对比起,我这搞了十几年C#的看不懂你文章里面的C#代码,你确定是C#?
悠悠然然
悠悠然然

引用来自“Kuangcp”的评论

总感觉你JAVA故意写那么长…明明用更少的代码可以实现。而且JAVA的繁杂是事实,这样的比较并没有意义~和同类比倒还行,Python groovy什么的

回复@Kuangcp : 那个不是我写的,因此没有故意不故意一说。那个是从百度搜出来的。
Kuangcp
Kuangcp
总感觉你JAVA故意写那么长…明明用更少的代码可以实现。而且JAVA的繁杂是事实,这样的比较并没有意义~和同类比倒还行,Python groovy什么的
I
InMath
感觉还是Java厉害
闲大赋
闲大赋
语言有有特定的应用领域,这样就有目的的发展
悠悠然然
悠悠然然

引用来自“评论专用”的评论

拿内置函数和完整算法比有意思吗

回复@评论专用 : 你以为我在秀算法,其实我在秀语言。
IOS IPhone 开发需要的开源库[编辑中.. 不断更新]

前言 我是 java & php 程序员,遇到了坑爹的iPhone,被逼无奈在崩溃的边缘下学习object-c ,在学习中遇到了很多 奇葩,无知,龌蹉,呕吐的问题(弱弱的说 : 有的些问题到现在还不知道具体的原...

海参
2013/06/03
0
6
算法导论第二章小试牛刀

Author: bakari   Date: 2015.9.11 《算法导论》真是一本让人又爱又恨的书,爱自然是因为它精简凝练的算法呈现,读来让人欲罢不能;至于恨,是因为它在进行算法分析的时候所体现的数学思想...

chambai
2015/09/11
0
0
每周一道算法题(三十)

本周题目难度级别'Hard',好久没做Hard级别的题目了,这周题目也很典型。。。 题目:给你一个合法且有解的数独,空白处用'.'代替,求解数独(可以认为只有唯一解) 题目比较典型,使用,用在...

CrazySteven
2017/10/15
0
0
linux 下安装node.js过程

今天在linux下安装node.js ,现在把过程记录下来 第一步:下载 到node.js官网下载node.js http://nodejs.org/dist/v0.8.1/node-v0.8.1.tar.gz 第二步:解压 (1)$ tar -xzvf node-v0.8.1.t...

Thyee
2012/07/06
0
0
tinyscript之序表操作

经常操作数据的同学们一定对序表这个名词很熟悉,从结构上来说跟数据库的表结构是类似的。tinyscript的序表是非常实用的数据结构,不仅可以处理数据库,也可以处理excel、文本文档等其他存储...

悠悠然然
2017/10/30
0
0

没有更多内容

加载失败,请刷新页面

加载更多

MySQL Replication 梳理详解

MySQL Replication 1 MySQL5.5以前的复制 异步、SQL线程串行化回放 MySQL内建的复制功能是构建大型,高性能应用程序的基础。主服务器将更新写入二进制日志文件,从服务器重新执行一遍来实现的...

PeakFang-BOK
12分钟前
1
0
.NET Core & ConsoleApp & appsettings.json

准备 Visual Studio 2017 .NET Core 2.1 新建控制台应用(.NET Core) 默认的 Program.cs // Program.csusing System;namespace ConsoleApp1{ class Program { static voi......

taadis
22分钟前
1
0
结合lucene谈谈日期的压缩问题

说起日期值的压缩,一般容易想到的办法是将日期转化成long类型,然后再通过变长整形进行压缩,我算了一下按照毫秒来算最多占用5个字节(可以通过“谈谈变长整型”中的表查看),确实节省了部...

FAT_mt
今天
1
0
导出私有函数与私有变量

在Go语言中, package中包含函数与变量通过identifier的首字母是否大写来决定它是否可以被其它package所访问。当一个函数或变量名称为小写字母时,默认是无法被其他package引用的. 有没有办法...

xtof
今天
1
0
new Date() 在Safari下的 Invalid Date问题

问题复现 var timeStr = '2018-11-11 00:00:00';var time = new Date(timeStr);// error: Invalid Date... 在safari浏览器下,time为Invalid Date, 导致后面代码执行错误; 其他浏览器诸...

会写代码的husky
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部