黑马程序员技术交流社区

标题: 中秋好礼,送亲友卷一枚!你值得拥有 [打印本页]

作者: hejinzhong    时间: 2014-9-4 13:34
标题: 中秋好礼,送亲友卷一枚!你值得拥有
本帖最后由 hejinzhong 于 2014-9-4 13:43 编辑

(1)时间:截止9月8日中秋节晚8点
(2)目的:一是为了中秋热闹下,更重要的是数据结构、算法是一个完美程序必不可少的一部分。为了能够学习更多的算法思想,只要回复任何一个和算法相关的程序,可以是自己写的,也可以是别出看到的。可以是你黑马入学测试中的算法题。只要是算法就可以。
(3)要求:
a.说明算法原理
b.回复结构清晰
c.有适当的注释
亲友卷来源:上次黑马币买的,滔哥发来的。

下面举个例子:

  1. /*
  2. * 螺旋矩阵是指一个呈螺旋状的矩阵,它的数字由第一行开始到右边不断变大,向下变大,
  3. * 向左变大,向上变大,如此循环。
  4. */

  5. public class Circle {
  6.         /**
  7.          * 接收三个参数,矩阵的行和列,以及起始数字
  8.          */
  9.         public static void main(String[] args) {
  10.                 helix(4,4,1);
  11.         }
  12.         /*
  13.          * 这个是左上角开始,顺时针转的螺旋
  14.          *
  15.          * 思想:先给最外层一圈赋值,再给第二圈赋值,直至结束
  16.          * 循环次数由行和列中较小一个决定,即为大于--较小者一半的---最小整数
  17.          */
  18.         public static void helix(int w,int h,int start){
  19.                 int[][] arr = new int[w][h];
  20.                 int left=0,top=0,right=w-1,botton=h-1;
  21.                 int max = w>h?(h+1)/2:(w+1)/2;
  22.                 for(int i=0;i<max;i++){
  23.                         for(int x=left;x<=right;x++){
  24.                                 arr[top][x] = start++;
  25.                         }
  26.                         top++;
  27.                         for(int y=top;y<=botton;y++){
  28.                                 arr[y][right] = start++;
  29.                         }
  30.                         right--;
  31.                         for(int z=right;z>=left;z--){
  32.                                 arr[botton][z]=start++;
  33.                         }
  34.                         botton--;
  35.                         for(int k=botton;k>=top;k--){
  36.                                 arr[k][left]=start++;
  37.                         }
  38.                         left++;
  39.                 }
  40.                
  41.                 for(int i=0;i<w;i++){
  42.                         for(int j=0;j<h;j++){
  43.                                 System.out.print(arr[i][j]+"\t");
  44.                         }
  45.                         System.out.println();
  46.                 }
  47.         }
  48. }
复制代码



作者: 宋超    时间: 2014-9-4 14:14
三维立体算法:
  1. /*
  2. * 3DCaptcha for .net
  3. *
  4. * http://www-personal.umich.edu/~mressl/3dcaptcha/     (php)
  5. * http://code.google.com/p/3dcaptcha/                  (php)
  6. *
  7. * Translate :  Aimeast
  8. * Blog      :  http://www.cnblogs.com/Aimeast/
  9. */

  10. using System;
  11. using System.Drawing;

  12. namespace Captcha
  13. {
  14.     public static class Captcha
  15.     {
  16.         private static double[] addVector(double[] a, double[] b)
  17.         {
  18.             return new double[] { a[0] + b[0], a[1] + b[1], a[2] + b[2] };
  19.         }

  20.         private static double[] scalarProduct(double[] vector, double scalar)
  21.         {
  22.             return new double[] { vector[0] * scalar, vector[1] * scalar, vector[2] * scalar };
  23.         }

  24.         private static double dotProduct(double[] a, double[] b)
  25.         {
  26.             return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
  27.         }

  28.         private static double norm(double[] vector)
  29.         {
  30.             return Math.Sqrt(dotProduct(vector, vector));
  31.         }

  32.         private static double[] normalize(double[] vector)
  33.         {
  34.             return scalarProduct(vector, 1.0 / norm(vector));
  35.         }

  36.         // http://en.wikipedia.org/wiki/Cross_product
  37.         private static double[] crossProduct(double[] a, double[] b)
  38.         {
  39.             return new double[] {
  40.                 (a[1] * b[2] - a[2] * b[1]),
  41.                 (a[2] * b[0] - a[0] * b[2]),
  42.                 (a[0] * b[1] - a[1] * b[0])
  43.             };
  44.         }

  45.         private static double[] vectorProductIndexed(double[] v, double[] m, int i)
  46.         {
  47.             return new double[]{
  48.                 v[i + 0] * m[0] + v[i + 1] * m[4] + v[i + 2] * m[8] + v[i + 3] * m[12],
  49.                 v[i + 0] * m[1] + v[i + 1] * m[5] + v[i + 2] * m[9] + v[i + 3] * m[13],
  50.                 v[i + 0] * m[2] + v[i + 1] * m[6] + v[i + 2] * m[10]+ v[i + 3] * m[14],
  51.                 v[i + 0] * m[3] + v[i + 1] * m[7] + v[i + 2] * m[11]+ v[i + 3] * m[15]
  52.             };
  53.         }

  54.         private static double[] vectorProduct(double[] v, double[] m)
  55.         {
  56.             return vectorProductIndexed(v, m, 0);
  57.         }

  58.         private static double[] matrixProduct(double[] a, double[] b)
  59.         {
  60.             double[] o1 = vectorProductIndexed(a, b, 0);
  61.             double[] o2 = vectorProductIndexed(a, b, 4);
  62.             double[] o3 = vectorProductIndexed(a, b, 8);
  63.             double[] o4 = vectorProductIndexed(a, b, 12);

  64.             return new double[]{
  65.                 o1[0], o1[1], o1[2], o1[3],
  66.                 o2[0], o2[1], o2[2], o2[3],
  67.                 o3[0], o3[1], o3[2], o3[3],
  68.                 o4[0], o4[1], o4[2], o4[3]
  69.             };
  70.         }

  71.         // http://graphics.idav.ucdavis.edu/education/GraphicsNotes/Camera-Transform/Camera-Transform.html
  72.         private static double[] cameraTransform(double[] C, double[] A)
  73.         {
  74.             double[] w = normalize(addVector(C, scalarProduct(A, -1)));
  75.             double[] y = new double[] { 0, 1, 0 };
  76.             double[] u = normalize(crossProduct(y, w));
  77.             double[] v = crossProduct(w, u);
  78.             double[] t = scalarProduct(C, -1);

  79.             return new double[]{
  80.                 u[0], v[0], w[0], 0,
  81.                 u[1], v[1], w[1], 0,
  82.                 u[2], v[2], w[2], 0,
  83.                 dotProduct(u, t), dotProduct(v, t), dotProduct(w, t), 1
  84.             };
  85.         }

  86.         // http://graphics.idav.ucdavis.edu/education/GraphicsNotes/Viewing-Transformation/Viewing-Transformation.html
  87.         private static double[] viewingTransform(double fov, double n, double f)
  88.         {
  89.             fov *= (Math.PI / 180);
  90.             double cot = 1.0 / Math.Tan(fov / 2);

  91.             return new double[]{
  92.                 cot,    0,      0,      0,
  93.                 0,      cot,    0,      0,
  94.                 0,      0,      (f + n) / (f - n),      -1,
  95.                 0,      0,      2 * f * n / (f - n),    0
  96.             };
  97.         }

  98.         public static Image Generate(string captchaText)
  99.         {
  100.             Random rnd = new Random();

  101.             // 3dcha parameters
  102.             int fontsize = 24;
  103.             Font font = new Font("Arial", fontsize);

  104.             SizeF sizeF;
  105.             using (Graphics g = Graphics.FromImage(new Bitmap(1, 1)))
  106.             {
  107.                 sizeF = g.MeasureString(captchaText, font, 0, StringFormat.GenericDefault);
  108.             }

  109.             int image2d_x = (int)sizeF.Width;
  110.             int image2d_y = (int)(fontsize * 1.3);

  111.             double bevel = 4;

  112.             // Create 2d image
  113.             Bitmap image2d = new Bitmap(image2d_x, image2d_y);
  114.             Color black = Color.Black;
  115.             Color white = Color.White;

  116.             // Paint 2d image
  117.             using (Graphics g = Graphics.FromImage(image2d))
  118.             {
  119.                 g.Clear(black);
  120.                 g.DrawString(captchaText, font, Brushes.White, 0, 0);
  121.             }
  122.             // Calculate projection matrix
  123.             double[] T = cameraTransform(
  124.                    new double[] { rnd.Next(-90, 90), -200, rnd.Next(150, 250) },
  125.                    new double[] { 0, 0, 0 }
  126.                 );
  127.             T = matrixProduct(
  128.                     T,
  129.                     viewingTransform(60, 300, 3000)
  130.                 );

  131.             // Calculate coordinates
  132.             double[][] coord = new double[image2d_x * image2d_y][];

  133.             int count = 0;
  134.             for (int y = 0; y < image2d_y; y += 2)
  135.             {
  136.                 for (int x = 0; x < image2d_x; x++)
  137.                 {
  138.                     // calculate x1, y1, x2, y2
  139.                     int xc = x - image2d_x / 2;
  140.                     int zc = y - image2d_y / 2;
  141.                     double yc = -(double)(image2d.GetPixel(x, y).ToArgb() & 0xff) / 256 * bevel;
  142.                     double[] xyz = new double[] { xc, yc, zc, 1 };
  143.                     xyz = vectorProduct(xyz, T);

  144.                     coord[count] = xyz;
  145.                     count++;
  146.                 }
  147.             }

  148.             // Create 3d image
  149.             int image3d_x = 256;
  150.             //$image3d_y = $image3d_x / 1.618;
  151.             int image3d_y = image3d_x * 9 / 16;
  152.             Bitmap image3d = new Bitmap(image3d_x, image3d_y);
  153.             Color fgcolor = Color.White;
  154.             Color bgcolor = Color.Black;
  155.             using (Graphics g = Graphics.FromImage(image3d))
  156.             {
  157.                 g.Clear(bgcolor);
  158.                 count = 0;
  159.                 double scale = 1.75 - (double)image2d_x / 400;
  160.                 for (int y = 0; y < image2d_y; y += 2)
  161.                 {
  162.                     for (int x = 0; x < image2d_x; x++)
  163.                     {
  164.                         if (x > 0)
  165.                         {
  166.                             double x0 = coord[count - 1][0] * scale + image3d_x / 2;
  167.                             double y0 = coord[count - 1][1] * scale + image3d_y / 2;
  168.                             double x1 = coord[count][0] * scale + image3d_x / 2;
  169.                             double y1 = coord[count][1] * scale + image3d_y / 2;
  170.                             g.DrawLine(new Pen(fgcolor), (float)x0, (float)y0, (float)x1, (float)y1);
  171.                         }
  172.                         count++;
  173.                     }
  174.                 }
  175.             }
  176.             return image3d;
  177.         }
  178.     }
  179. }
复制代码
使用方法:
  1. this.BackgroundImage = Captcha.Generate("Code");
复制代码


效果图:

作者: 28了还能学吗    时间: 2014-9-4 14:40
宋超 发表于 2014-9-4 14:14
三维立体算法:
使用方法:

都是大牛  
作者: Huberry    时间: 2014-9-4 14:59
本帖最后由 Huberry 于 2014-9-4 15:03 编辑
  1. /*
  2. 快速排序:
  3. 步骤:
  4. 1、选择一个标准元素
  5. 2、使用该标准元素分割数组,使得比该元素小的元素在它的左边,比它大的在右边。并
  6.         把标准元素放在合适的位置。  
  7. 3、根据标准元素最后确定的位置,把数组分成三部分,左边的,右边的,枢纽元素自己,
  8.         然后再对左边的和右边的分别递归调用快速排序算法即可。  
  9. */


  10. class QuickSort{
  11.         public static void main(String[] args) {
  12.                 int [] x = new int[]{16,54,5,61,12,31,25,11,76,22,10};
  13.                
  14.                 sopArray(x);
  15.                
  16.                quickSort(x,0,x.length-1);
  17.                
  18.                sopArray(x);
  19.         }
  20.         private static void quickSort(int[] arr, int left, int right) {
  21.                 int l,r; //左右哨兵 ,l为左哨兵位置,r为右哨兵位置
  22.                 int baseNum; //存储基准数
  23.                
  24.                 if(left > right)
  25.                         return;
  26.                
  27.                 baseNum = arr[left]; //第一次基准数默认为数组首位
  28.                 l = left;  //左哨兵从左边出发扫描
  29.                 r = right; //右哨兵从右边出发扫描
  30.                 while(l != r) {
  31.                         //先从右边开始往左扫描,找到第一个比基准数小的
  32.                         while(arr[r] >= baseNum && l < r)
  33.                                 r--;
  34.                         //再从左边开始往右扫描,找到第一个比基准数大的
  35.                         while(arr[l] <= baseNum && l < r)
  36.                                 l++;
  37.                         //交换两个数位置
  38.                         if(l < r) {
  39.                                 int temp = arr[l];
  40.                                 arr[l] = arr[r];
  41.                                 arr[r] = temp;
  42.                         }
  43.                 }
  44.                
  45.                 //基准数归位
  46.                 arr[left] = arr[l];
  47.                 arr[l] = baseNum;
  48.                
  49.                 //递归处理左边
  50.                 quickSort(arr, left, l - 1);
  51.                 //递归处理右边
  52.                 quickSort(arr, l + 1, right);
  53.         }
复制代码

作者: 宋超    时间: 2014-9-4 15:09
楼主 说好的亲友卷呢 。460791814 谢谢
作者: hejinzhong    时间: 2014-9-4 15:21
宋超 发表于 2014-9-4 15:09
楼主 说好的亲友卷呢 。460791814 谢谢

最后随机给,时间还没到,你那写的来点注释!
作者: 宋超    时间: 2014-9-4 15:45
hejinzhong 发表于 2014-9-4 15:21
最后随机给,时间还没到,你那写的来点注释!

加好友哇 ,你好多黑马币
作者: z-翔    时间: 2014-9-4 16:03
我讨厌不加注释的代码...
作者: 夜半风    时间: 2014-9-4 16:22
不加注释的代码就和吃没吃过的东西 但是没说明怎么吃  的感觉是一样一样的
作者: jiangweibin2573    时间: 2014-9-4 17:08


  1. 约瑟夫环是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围,从1开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到最后一个人。
  2. //下面是报数14

  3. import java.util.Scanner;
  4. public class Ex14 {
  5.         public static void main(String[] args) {
  6.                 Scanner s = new Scanner(System.in);
  7.                 int n = s.nextInt();
  8.                 boolean[] arr = new boolean[n];
  9.                 for (int i = 0; i < arr.length; i++) {
  10.                         arr[i] = true;// 下标为TRUE时说明还在圈里
  11.                 }
  12.                 int leftCount = n;
  13.                 int countNum = 0;
  14.                 int index = 0;
  15.                 while (leftCount > 1) {
  16.                         if (arr[index] == true) {// 当在圈里时
  17.                                 countNum++; // 报数递加
  18.                                 if (countNum == 14) {// 报道14时
  19.                                         countNum = 0;// 从零开始继续报数
  20.                                         arr[index] = false;// 此人退出圈子
  21.                                         leftCount--;// 剩余人数减一
  22.                                 }
  23.                         }
  24.                         index++;// 每报一次数,下标加一
  25.                         if (index == n) {// 是循环数数,当下标大于n时,说明已经数了一圈,
  26.                                 index = 0;// 将下标设为零重新开始。
  27.                         }
  28.                 }
  29.                 for (int i = 0; i < n; i++) {
  30.                         if (arr[i] == true) {
  31.                                 System.out.println(i + 1);
  32.                         }
  33.                 }
  34.         }
  35. }

复制代码


作者: ☆枫の云    时间: 2014-9-4 21:25
入学测试我做了这个题了,做的要疯了。。。
作者: Fightin黑马    时间: 2014-9-4 21:59
约瑟夫环问题:500个人站成一圈,从一开始数,数到三或三的倍数则被杀掉,下一个人接着数,幸运的是第几个人

  1. import java.util.LinkedList;

  2. public class Test7 {

  3.         public static void main(String[] args) {
  4.                 LinkedList<Integer> num=new LinkedList<>();                                                //定义list集合接收1~500的数据
  5.                 for(int i=1;i<=500;i++){                                                                                                                        //将这500个数据存入集合
  6.                         num.add(i);
  7.                 }
  8.                 int count=0;                                                                                                                                                        //定义计数器用来数数

  9.                 for(int i=0;i<num.size();){                                                                                                                //遍历集合
  10.                         count++;                                                                                                                                                        //计数器增加
  11.                         if(count%3==0){               
  12.                         num.remove(i--);                                                                                                                                //当计数器为3的倍数的时候,从集合中去掉当前的数,去掉当前的数后,另索引回拨一个
  13.                         }
  14.                         i++;                                                                                                                                                                        //下一个数
  15.                         if((i==num.size())&&num.size()!=1){                                                                        //当索引等于集合个数时,并且集合元素大于1,则从头开始遍历集合
  16.                                 i=0;
  17.                         }
  18.                 }
  19.                 System.out.println("幸存的是第"+num.get(0)+"人");                                //最后留下的一个数就是那个幸运的人
  20.         }

  21. }
复制代码

作者: 许愿じ☆VE杰    时间: 2014-9-4 22:28
学习了~
作者: 黄凯旋    时间: 2014-9-4 22:35
只是看看o.o
作者: 柳超    时间: 2014-9-4 22:37
  1. import java.util.Scanner;
  2. class  MatrixArray
  3. {
  4.         public static void main(String[] args)
  5.         {
  6.                 Scanner input = new Scanner(System.in);
  7.                 System.out.println("请输入矩阵的宽度:");
  8.                 int length=input.nextInt();
  9.                 //矩阵用二维数组位置可以一一对应
  10.                 int[][] arr = new int[length][length];
  11.                 //定义一个变量控制循环所在位置,当count 每自增一次循环内圈进入一次
  12.                 int count =0;
  13.                 //字义数值,每次赋值都自增一次让值一直是+1
  14.                 int number=1;
  15.                 //利用循环控制count自增,以达到控制循环所在位置,不断向内赋值
  16.                 /*
  17.                 while(count<length/2+1)
  18.                 {//每行数据赋值个数相同都是length-1个
  19.                         //for循环输入第一行数据,其中不包括最后一个数
  20.                         for(int x =count;x<length-1-count;x++,number++)
  21.                         {
  22.                                 arr[count][x]=number;
  23.                         }
  24.                         //for循环输入纵向还没赋值的最后一排的数据,其中不包括最下面一个数
  25.                         for(int x =count;x<length-1-count;x++,number++)
  26.                         {
  27.                                 arr[x][length-1-count]=number;
  28.                         }
  29.                         //for循环输入还没赋值的最下边一行数据,其中不包括行第一个数
  30.                         for(int x = length-1-count;x>count;x--,number++)
  31.                         {
  32.                                 arr[length-1-count][x]=number;
  33.                         }
  34.                         //for循环输入还没赋值的纵向第一排数据,其中不包括最上面的数
  35.                         for(int x = length-1-count;x>count;x--,number++)
  36.                         {
  37.                                 arr[x][count]=number;
  38.                         }
  39.                
  40.                         count++;
  41.                 }
  42.                 */
  43.                
  44.                 //这种方式会把中间位置重复赋值,运算完成后需要对中间位置进行判定
  45.                 //此时 中间公位置的元素赋值不正确
  46.                 while(count<length/2+1)
  47.                 {//第次赋值数据不相同,上和下赋值时数据个数为length,左右赋值为length-2
  48.                         //for循环输入第一行数据,其中不包括最后一个数
  49.                         for(int x =count;x<length-count;x++,number++)
  50.                         {
  51.                                 arr[count][x]=number;
  52.                         }
  53.                         //for循环输入纵向还没赋值的最后一排的数据,其中不包括最下面一个数
  54.                         for(int x =count+1;x<length-1-count;x++,number++)
  55.                         {
  56.                                 arr[x][length-1-count]=number;
  57.                         }
  58.                         //for循环输入还没赋值的最下边一行数据,其中不包括行第一个数
  59.                         for(int x = length-count-1;x>=count;x--,number++)
  60.                         {       
  61.                                 if((length%2==1)&&(length - 1 - count) == (length/2))
  62.                                 {
  63.                                         break;
  64.                                 }
  65.                                 arr[length-1-count][x]=number;
  66.                         }
  67.                         //for循环输入还没赋值的纵向第一排数据,其中不包括最上面的数
  68.                         for(int x = length-2-count;x>count;x--,number++)
  69.                         {
  70.                                 arr[x][count]=number;
  71.                         }
  72.                
  73.                         count++;
  74.                 }



  75.                
  76.                 for(int x=0;x<length;x++)
  77.                 {
  78.                         for(int y=0;y<length;y++)
  79.                         {
  80.                                 System.out.print(arr[x][y]+"\t");
  81.                         }
  82.                         System.out.println();
  83.                 }
  84.         }
  85. }
复制代码

我的螺旋矩阵的作法可能没有你的简单应该说更好理解吧
作者: 塞肥肥塞牙人    时间: 2014-9-4 22:48
学 习 了
作者: ╃→梅飛揚之城    时间: 2014-9-5 00:18
学习一下
作者: 戏言丶    时间: 2014-9-5 00:33
我纯属来凑热闹的:lol




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2