数据结构(二十)——综合案例练习

前言

  我们通过前面的三篇文章,给大家介绍了日常生活中常用的十大算法,主要包括二分查找、分治法、动态规划KMP算法、贪心算法、Prim算法、Kruskal算法Dijstra算法、Floyd算法以及马踏棋盘问题。这些算法是我们日常生活中作重要的,是建立我们编程思想的重要环节。至此,我们数据结构与算法的所有知识点全部介绍完毕。本篇文章作为收尾,给大家在网上找了一些典型案例帮助大家更好的提升自己在数据结构与算法中的理解。本文主要给大家介绍磁盘问题、公交车、画图、矩阵中查找单词路径数、球和篮子以及扔石头等六个问题,首先给大家介绍常见的磁盘问题。

一、磁盘问题

1、 问题陈述

  You are given a String disk representing the clusters on a disk. An ‘X’ represents a used cluster, and a ‘.’ represents an available cluster. You are also given an int size representing the size, in clusters, of a file waiting to be written to disk. A file can only be stored in clusters not already being used.
  我们翻译成中文为:你会得到一个字符串表示磁盘的簇,一个 'X’表示用过的簇,一个 ‘.’ 表示一个可以使用的簇,你还会得到一个整数表示准备存入磁盘的文件大小,文件仅可以存在没有使用过的簇中。
  Return the minimum number of groups of consecutive clusters needed to store the file on the disk. (The disk does not wrap around at the end.) Return -1 if the disk does not have enough space available to store the file.
  返回一个连续的最小簇数来保存文件,如果磁盘没有足够的空间,就返回 -1。
  其中的定义以及类名规定如下:
  1、定义——Definition
  2、类名——DiskClusters
  3、方法——minimumFragmentation
   4、参数——String, int
   5、返回——int
  6、方法签名——int minimumFragmentation(String disk, int size),(be sure your method is public) 一定要 public
  7、约束——disk will contain between 1 and 50 characters, inclusive.Each character of disk will be ‘X’ or ‘.’.size will be between 1 and 50, inclusive.
  8、举例:
  0)、".",2, Returns: -1 We can’t fit the file on the disk.
  1)、".XXXXXXXX.XXXXXX.XX.X.X.",6,Returns: 6,There is only ever one cluster together, so all six clusters are separated.
  2)、“XX…XX…X.XX…X…X.XX…XXXX…XX…XXXXX.”,12,Returns: 2,We fit eight clusters together, and four clusters together.
  3)、".X.XXXX…XX…X…X…XX.X…X.",20
Returns: 3
  4)、"…X…X…X",11,Returns: -1
  In conclusion,This problem statement is the exclusive and proprietary property of TopCoder, Inc. Any unauthorized use or reproduction of this information without the prior written consent of TopCoder, Inc. is strictly prohibited. ©2003, TopCoder, Inc. All rights reserved.

2、代码实现

  由于此代码我们考虑其利用率,因此,将测试和方法实现分别通过ClustersTextDiskCluster来实现,具体结构如图所示:

  因此,我们在运行ClustersText之前,首先实现DiskCluster,具体实现DiskCluster代码如下:

public class DiskClusters {
    
    
    int[] clusters=new int[50];
    public int minimumFragmentation(String disk, int size) {
    
    
        char[] array=disk.toCharArray();
        int space=0,j=0,count=0;
        for (int i=0;i<array.length;i++) {
    
    
            if (array[i]=='.') {
    
    
                space++;
                clusters[j]+=1;
            }
            else if (i!=array.length-1) {
    
    
                if (array[i+1]=='.')
                    j++;
            }
        }
        if (space<size)
            return -1;
        else {
    
    
            sort(j+1);
            int sum=0;
            for (int i=0;i<=j;i++) {
    
    
                count++;
                sum+=clusters[i];
                if (sum>=size)
                    break;
            }
        }
        return count;
    }
    void sort(int length) {
    
    
        int i,j,k,temp;
        for (i=0;i<length;i++) {
    
    
            k=i;
            for (j=i;j<length;j++) {
    
    
                if (clusters[k]<clusters[j])
                    k=j;
            }
            if (k!=i) {
    
    
                temp=clusters[k];
                clusters[k]=clusters[i];
                clusters[i]=temp;
            }
        }
    }
}

  然后,我们实现ClusterText进行磁盘测试,具体实现如下:

public class ClustersTest {
    
    
    public static boolean Test1() {
    
    
        DiskClusters dc=new DiskClusters();
        String disk=".XXXXXXXX.XXXXXX.XX.X.X.";
        int size=6;
        int result=6;
        return result==dc.minimumFragmentation(disk,size);
    }
    public static boolean Test2() {
    
    
        DiskClusters dc=new DiskClusters();
        String disk="XX..XX....X.XX........X...X.XX...XXXX..XX...XXXXX.";
        int size=12;
        int result=2;
        return result==dc.minimumFragmentation(disk,size);
    }
    public static boolean Test3() {
    
    
        DiskClusters dc=new DiskClusters();
        String disk=".X.XXXX.......XX....X.....X............XX.X.....X.";
        int size=20;
        int result=3;
        return result==dc.minimumFragmentation(disk,size);
    }
    public static boolean Test4() {
    
    
        DiskClusters dc=new DiskClusters();
        String disk="....X...X..X";
        int size=11;
        int result=-1;
        return result==dc.minimumFragmentation(disk,size);
    }
    public static void main(String[] args) {
    
    
        if (Test1())
            System.out.println ("Test1 OK");
        if (Test2())
            System.out.println ("Test2 OK");
        if (Test3())
            System.out.println ("Test3 OK");
        if (Test4())
            System.out.println ("Test4 OK");
    }
}

  执行的结果如下

二、公交车问题

1、问题陈述

  You are given a String[] cityMap representing the layout of a city. The city consists of blocks. The first element of cityMap represents the first row of blocks, etc. A ‘B’ character indicates a location where there is a bus stop. There will be exactly one ‘X’ character, indicating your location. All other characters will be ‘.’. You are also given an int walkingDistance, which is the maximum distance you are willing to walk to a bus stop. The distance should be calculated as the number of blocks vertically plus the number of blocks horizontally. Return the number of bus stops that are within walking distance of your current location.
  我们翻译成中文为:给定一个String[]cityMap代表城市布局,城市包括街区.cityMap的一个元素代表街区的第一行,等等.A ‘B’字符表示公交车站所在的位置.用单个的’X’代表你所在的位置.所有其他的字符是’.'给定一个int型的walkingDistance,代表你去公交站的最远距离。距离的计算是按照垂直经过的街区的数量加上水平经过的街区的数量。返回从你当前位置走过的距离的公交车站的数量
  其中的定义以及类名规定如下:
  1、定义——Definition
  2、类名——BusStops
  3、方法——countStops
   4、参数——String, int
   5、返回——int
  6、方法签名——int countStops(String[] cityMap, int walkingDistance)
(be sure your method is public)
  7、约束——disk will contain between 1 and 50 characters, inclusive.Each character of disk will be ‘X’ or ‘.’.size will be between 1 and 50, inclusive.
  8、举例:
  0)、
{"…B.",
“…”,
“…X.B”,
“…”,
“B…”},3, Returns: 2 You can reach the bus stop at the top (3 units away), or on the right (2 units away). The one in the lower left is 4 units away, which is too far…
  1)、
{“B.B…”,
“…”,
“B…”,
“…”,
“…X”},8,Returns: 3,A distance of 8 can get us anywhere on the map, so we can reach all 3 bus stops.
  2)、
{“BBBBB”,
“BB.BB”,
“B.X.B”,
“BB.BB”,
“BBBBB”},1,Returns: ,0,Plenty of bus stops, but unfortunately we cannot reach any of them.
  3)、
{“B…B…”,
“.B…B”,
“…B…”,
“…B.X.”,
“B.B.B.”,
“.B.B.B”},20
Returns: 7
  In conclusion,This problem statement is the exclusive and proprietary property of TopCoder, Inc. Any unauthorized use or reproduction of this information without the prior written consent of TopCoder, Inc. is strictly prohibited. ©2003, TopCoder, Inc. All rights reserved.

2、代码实现

  由于此代码我们考虑其利用率,因此,将测试和方法实现分别通过BusStopsBusStopsTest来实现。

  因此,我们在运行BusStopsText之前,首先实现BusStops,具体实现BusStops代码如下:

import java.util.*;
public class BusStops {
    
    
    class Location {
    
    
        int x,y;
    }
    int countStops(String[] cityMap, int walkingDistance) {
    
    
        int count=0;
        Location current=new Location();
        Vector v=new Vector();
        for (int i=0;i<cityMap.length;i++) {
    
    
            for (int j=0;j<cityMap[i].length();j++) {
    
    
                char c=cityMap[i].charAt(j);
                if (c!='.') {
    
    
                    if (c=='X') {
    
    
                        current.x=i;
                        current.y=j;
                    }
                    else {
    
    
                        Location l=new Location();
                        l.x=i;
                        l.y=j;
                        v.add(l);
                    }
                }
            }
        }
        Enumeration em=v.elements();
        while (em.hasMoreElements()) {
    
    
            Location l=(Location)em.nextElement();
            if (judgeReach(current,l,walkingDistance)) {
    
    
                count++;
            }
        }
        return count;
    }
    boolean judgeReach(Location l1,Location l2,int d) {
    
    
        int direction=Math.abs(l1.x-l2.x)+Math.abs(l1.y-l2.y);
        if (direction<=d) {
    
    
            return true;
        }
        else return false;
    }
}

  然后,我们实现BusStopsText进行磁盘测试,具体实现如下:

public class BusStopTest {
    
    
    public boolean Test1() {
    
    
        BusStops bs=new BusStops();
        String[] map={
    
    "...B.",
                ".....",
                "..X.B",
                ".....",
                "B...."};
        int d=3;
        int result=2;
        return result==bs.countStops(map,d);
    }
    public boolean Test2() {
    
    
        BusStops bs=new BusStops();
        String[] map={
    
    "B.B..",
                ".....",
                "B....",
                ".....",
                "....X"};
        int d=8;
        int result=3;
        return result==bs.countStops(map,d);
    }
    public boolean Test3() {
    
    
        BusStops bs=new BusStops();
        String[] map={
    
    "BBBBB",
                "BB.BB",
                "B.X.B",
                "BB.BB",
                "BBBBB"};
        int d=1;
        int result=0;
        return result==bs.countStops(map,d);
    }
    public boolean Test4() {
    
    
        BusStops bs=new BusStops();
        String[] map={
    
    "B..B..",
                ".B...B",
                "..B...",
                "..B.X.",
                "B.B.B.",
                ".B.B.B"};
        int d=3;
        int result=7;
        return result==bs.countStops(map,d);
    }
    public static void main(String[] args) {
    
    

        String[] map={
    
    "BBBBB",
                "BB.BB",
                "B.X.B",
                "BB.BB",
                "BBBBB"};

        System.out.println (map);

        BusStopTest bs=new BusStopTest();
        if (bs.Test1()) {
    
    
            System.out.println ("Test1 OK");
        }
        if (bs.Test2()) {
    
    
            System.out.println ("Test2 OK");
        }
        if (bs.Test3()) {
    
    
            System.out.println ("Test3 OK");
        }
        if (bs.Test4()) {
    
    
            System.out.println ("Test4 OK");
        }
    }
}

  具体执行的结果如图所示:

三、画图问题

1、问题陈述

  A simple line drawing program uses a blank 20 x 20 pixel canvas and a directional cursor that starts at the upper left corner pointing straight down. The upper left corner of the canvas is at (0, 0) and the lower right corner is at (19, 19). You are given a String[], commands, each element of which contains one of two possible commands. A command of the form “FORWARD x” means that the cursor should move forward by x pixels. Each pixel on its path, including the start and end points, is painted black. The only other command is “LEFT”, which means that the cursor should change its direction by 90 degrees counterclockwise. So, if the cursor is initially pointing straight down and it receives a single “LEFT” command, it will end up pointing straight to the right. Execute all the commands in order and return the resulting 20 x 20 pixel canvas as a String[] where character j of element i represents the pixel at (i, j). Black pixels should be represented as uppercase ‘X’ characters and blank pixels should be represented as ‘.’ characters.
  我们翻译成中文为:这是一个简单的画图软件,画布为 2020 的像素,初始时光标位置处于画布的左上角,方向垂直向下,左上角的坐标为 (0,0),右下角坐标为 (19,19),你会得到一个字符串数组组成的命令,每一个元素包含一个控制命令,命令有两种类型,一个命令是:FORWARD X, 向前走,走的像素由 X 确定。仅有的另一个命令是:LEFT ,用来控制光标向左转,例如:初始时光标垂直向下,向左转后,方向变为向右,执行完所有的命令后,返回一个用字符串数组组成的画布,此字符串数组的第 I 个元素的第 J 个字符表示画布的(X,Y ) 内容,走过的像素用 “X" 表示,空白的像素用 “." 表示。
  其中的定义以及类名规定如下:
  1、定义——Definition
  2、类名——DrawLines
  3、方法——execute
   4、参数——String[]
   5、返回——String[]
  6、方法的签名——String[] execute(String[] commands),(be sure your method is public)
  7、约束——disk will contain between 1 and 50 characters, Each element of commands will be formatted as either “LEFT” or “FORWARD x” (quotes for clarity only), where x is an integer between 1 and 19, inclusive, with no extra leading zeros.When executing the commands in order, the cursor will never leave the 20 x 20 pixel canvas.
  8、举例:
  0)、
{“FORWARD 19”, “LEFT”, “FORWARD 19”, “LEFT”, “FORWARD 19”, “LEFT”, “FORWARD 19”},{“XXXXXXXXXXXXXXXXXXXX”,
“X…X”,
“X…X”,
“X…X”,
“X…X”,
“X…X”,
“X…X”,
“X…X”,
“X…X”,
“X…X”,
“X…X”,
“X…X”,
“X…X”,
“X…X”,
“X…X”,
“X…X”,
“X…X”,
“X…X”,
“X…X”,
“XXXXXXXXXXXXXXXXXXXX” },This sequence of commands draws a 20 x 20 outline of a square. The cursor is initially at (0, 0) pointing straight down. It then travels to (0, 19) after the first FORWARD command, painting each pixel along its path with a '
’. It then rotates 90 degrees left, travels to (19, 19), rotates 90 degrees left, travels to (19, 0), rotates 90 degrees left, and finally travels back to (0, 0).
  In conclusion,This problem statement is the exclusive and proprietary property of TopCoder, Inc. Any unauthorized use or reproduction of this information without the prior written consent of TopCoder, Inc. is strictly prohibited. ©2003, TopCoder, Inc. All rights reserved.

2、代码实现

  我们首先实现DrawLines函数,具体实现如下:

public class DrawLines {
    
    
    String[] execute(String[] commands) {
    
    
        char[][] map=new char[20][20];
        int x=0,y=0,direction=0,i,j;
        String[] result=new String[20];
        for (i=0;i<20;i++) {
    
    
            result[i]="";
            for (j=0;j<20;j++)
                map[i][j]='.';
        }
        for (int k=0;k<commands.length;k++) {
    
    
            if (commands[k].equals("LEFT")) {
    
    
                direction=(direction+1)%4;
            }else if(commands[k].split(" ")[0].equals("FORWARD")) {
    
    
                map[0][0]='X';
                int step=Integer.parseInt(commands[k].split(" ")[1]);
                switch (direction) {
    
    
                    case 0:
                        for (i=0;i<step;i++) {
    
    
                            if (x<20)
                                map[++x][y]='X';
                            else break;
                        }
                        break;
                    case 1:
                        for (i=0;i<step;i++) {
    
    
                            if (y<20)
                                map[x][++y]='X';
                            else break;
                        }
                        break;
                    case 2:
                        for (i=0;i<step;i++) {
    
    
                            if (x>=0)
                                map[--x][y]='X';
                            else break;
                        }
                        break;
                    case 3:
                        for (i=0;i<step;i++) {
    
    
                            if (y>=0)
                                map[x][--y]='X';
                            else break;
                        }
                        break;
                }
            }
        }
        for (i=0;i<20;i++)
            for (j=0;j<20;j++)
                result[i]+=map[i][j];
        return result;
    }
    public static void main(String[] args) {
    
    
        String[] commands={
    
    "LEFT", "FORWARD 19", "LEFT", "LEFT", "LEFT",
                "FORWARD 18", "LEFT", "LEFT", "LEFT", "FORWARD 17",
                "LEFT", "LEFT", "LEFT", "FORWARD 16", "LEFT",
                "LEFT", "LEFT", "FORWARD 15", "LEFT", "LEFT", "LEFT",
                "FORWARD 14", "LEFT", "LEFT", "LEFT", "FORWARD 13",
                "LEFT", "LEFT", "LEFT", "FORWARD 12", "LEFT", "LEFT",
                "LEFT", "FORWARD 11", "LEFT", "LEFT", "LEFT", "FORWARD 10",
                "LEFT", "LEFT", "LEFT", "FORWARD 9", "LEFT", "LEFT",
                "LEFT", "FORWARD 8", "LEFT", "LEFT", "LEFT", "FORWARD 7"};
        DrawLines dl=new DrawLines();
        String[] result=dl.execute(commands);
        for (int i=0;i<20;i++)
            System.out.println (result[i]);
    }
}

  执行的结果如下:

  由于此代码我们考虑其利用率,因此,将测试和方法实现分别通过GoogleTesttestMain来实现。
  因此,我们在运行testMain之前,首先实现GoogleTest,具体实现GoogleTest代码如下:

public class GoogleTest {
    
    
    public boolean compareString(String[] s1,String[] s2) {
    
    
        if (s1==null||s2==null||s1.length!=s2.length)
            return false;
        for (int i=0;i<s1.length;i++) {
    
    
            if (!s1[i].equals(s2[i]))
                return false;
        }
        return true;
    }
    public boolean Test1() {
    
    
        String[] result=
                {
    
    "XXXXXXXXXXXXXXXXXXXX",
                        "X..................X",
                        "X..................X",
                        "X..................X",
                        "X..................X",
                        "X..................X",
                        "X..................X",
                        "X..................X",
                        "X..................X",
                        "X..................X",
                        "X..................X",
                        "X..................X",
                        "X..................X",
                        "X..................X",
                        "X..................X",
                        "X..................X",
                        "X..................X",
                        "X..................X",
                        "X..................X",
                        "XXXXXXXXXXXXXXXXXXXX"};
        String[] input={
    
    "FORWARD 19", "LEFT", "FORWARD 19", "LEFT", "FORWARD 19", "LEFT", "FORWARD 19"};
        DrawLines dl=new DrawLines();
        String[] test=dl.execute(input);
        return this.compareString(test,result);
    }
    public boolean Test2() {
    
    
        String[] result=
                {
    
    "....................",
                        "....................",
                        "....................",
                        "....................",
                        "....................",
                        "....................",
                        "....................",
                        "....................",
                        "....................",
                        "....................",
                        "....................",
                        "....................",
                        "....................",
                        "....................",
                        "....................",
                        "....................",
                        "....................",
                        "....................",
                        "....................",
                        "...................." };
        String[] input={
    
    "LEFT", "LEFT", "LEFT", "LEFT", "LEFT", "LEFT", "LEFT", "LEFT"};
        DrawLines dl=new DrawLines();
        String[] test=dl.execute(input);
        return this.compareString(test,result);
    }
    public boolean Test3() {
    
    
        String[] result=
                {
    
    "X...................",
                        "X...................",
                        "....................",
                        "....................",
                        "....................",
                        "....................",
                        "....................",
                        "....................",
                        "....................",
                        "....................",
                        "....................",
                        "....................",
                        "....................",
                        "....................",
                        "....................",
                        "....................",
                        "....................",
                        "....................",
                        "....................",
                        "...................." };
        String[] input={
    
    "FORWARD 1"};
        DrawLines dl=new DrawLines();
        String[] test=dl.execute(input);
        return this.compareString(test,result);
    }
    public boolean Test4() {
    
    
        String[] result=
                {
    
    "XXXXXXXXXXXXXXXXXXXX",
                        "...................X",
                        "..XXXXXXXXXXXXXXXX.X",
                        "..X..............X.X",
                        "..X.XXXXXXXXXXXX.X.X",
                        "..X.X..........X.X.X",
                        "..X.X.XXXXXXXX.X.X.X",
                        "..X.X.X........X.X.X",
                        "..X.X.X........X.X.X",
                        "..X.X.X........X.X.X",
                        "..X.X.X........X.X.X",
                        "..X.X.X........X.X.X",
                        "..X.X.X........X.X.X",
                        "..X.X.X........X.X.X",
                        "..X.X.XXXXXXXXXX.X.X",
                        "..X.X............X.X",
                        "..X.XXXXXXXXXXXXXX.X",
                        "..X................X",
                        "..XXXXXXXXXXXXXXXXXX",
                        "...................." };
        String[] input={
    
    "LEFT", "FORWARD 19", "LEFT", "LEFT", "LEFT",
                "FORWARD 18", "LEFT", "LEFT", "LEFT", "FORWARD 17",
                "LEFT", "LEFT", "LEFT", "FORWARD 16", "LEFT",
                "LEFT", "LEFT", "FORWARD 15", "LEFT", "LEFT", "LEFT",
                "FORWARD 14", "LEFT", "LEFT", "LEFT", "FORWARD 13",
                "LEFT", "LEFT", "LEFT", "FORWARD 12", "LEFT", "LEFT",
                "LEFT", "FORWARD 11", "LEFT", "LEFT", "LEFT", "FORWARD 10",
                "LEFT", "LEFT", "LEFT", "FORWARD 9", "LEFT", "LEFT",
                "LEFT", "FORWARD 8", "LEFT", "LEFT", "LEFT", "FORWARD 7"};
        DrawLines dl=new DrawLines();
        String[] test=dl.execute(input);
        return this.compareString(test,result);
    }
}

  然后,我们实现TextMain进行磁盘测试,具体实现如下:

public class TestMain {
    
    
    public static void main(String[] args) {
    
    
        GoogleTest gt=new GoogleTest();
        if (gt.Test1())
            System.out.println ("Test1 ok");
        if (gt.Test2())
            System.out.println ("Test2 ok");
        if (gt.Test3())
            System.out.println ("Test3 ok");
        if (gt.Test4())
            System.out.println ("Test4 ok");
    }
}

  具体执行结果如下:

四、矩阵中查找单词路径数

1、问题陈述

  You are given a String[] grid representing a rectangular grid of letters. You are also given a String find, a word you are to find within the grid. The starting point may be anywhere in the grid. The path may move up, down, left, right, or diagonally from one letter to the next, and may use letters in the grid more than once, but you may not stay on the same cell twice in a row (see example 6 for clarification).
  我们翻译成中文为:你会得到一个字符串的数组,表示一个字符的矩阵,你还会得到一个字符串查找,需要在矩阵中查找这个单词,单词的开始点可能在矩阵的任意位置,方向可以是上,下,左,右,或者对角,也可能多次使用矩阵中的字符,但是你不可以在同一行的相同单元中两次。见例6
  You are to return an int indicating the number of ways find can be found within the grid. If the result is more than 1,000,000,000, return -1.
  你需要返回一个整数,表示在矩阵中发现的路径个数,如果返回的路径超过 1,000,000,000,就返回 -1。
  其中的定义以及类名规定如下:
  1、定义——Definition
  2、类名——WordPath
  3、方法——countPaths
   4、参数——String[], String
   5、返回——int
  6、方法签名——int countPaths(String[] grid, String find)
(be sure your method is public)
  7、约束——disk will contain between 1 and 50 characters,Each element of grid will contain between 1 and 50 uppercase (‘A’-‘Z’) letters, inclusive.,Each element of grid will contain the same number of characters.find will contain between 1 and 50 uppercase (‘A’-‘Z’) letters, inclusive.
  8、举例:
  0)、
{“ABC”,
“FED”,
“GHI”}
“ABCDEFGHI”,1, Returns: 1 There is only one way to trace this path. Each letter is used exactly once.
  1)、
{“ABC”,
“FED”,
“GAI”}
“ABCDEA”,2,Returns: 2,Once we get to the ‘E’, we can choose one of two directions for the final ‘A’.
  2)、
{“ABC”,
“DEF”,
“GHI”}
“ABCD”,0,Returns: ,0,We can trace a path for “ABC”, but there’s no way to complete a path to the letter ‘D’.
  3)、
{“AA”,
“AA”}
“AAAA”,108
Returns: 108,We can start from any of the four locations. From each location, we can then move in any of the three possible directions for our second letter, and again for the third and fourth letter. 4 * 3 * 3 * 3 = 108.
  In conclusion,This problem statement is the exclusive and proprietary property of TopCoder, Inc. Any unauthorized use or reproduction of this information without the prior written consent of TopCoder, Inc. is strictly prohibited. ©2003, TopCoder, Inc. All rights reserved.

2、代码实现

  由于此代码我们考虑其利用率,因此,将测试和方法实现分别通过WordPathWordTest来实现。
  因此,我们在运行WordText之前,首先实现WordPath,具体实现WordPath代码如下:

public class WordPath {
    
    
    int m,n,count=0;
    char[] word;
    char[][] matrix;
    public int countPaths(String[] grid, String find) {
    
    
        m=grid.length;
        n=grid[0].length();
        matrix=new char[m][n];
        word=find.toCharArray();
        int i,j;
        for (i=0;i<m;i++) {
    
    
            for (j=0;j<n;j++) {
    
    
                matrix[i][j]=grid[i].charAt(j);
            }
        }
        for (i=0;i<m;i++) {
    
    
            for (j=0;j<n;j++) {
    
    
                if (matrix[i][j]==word[0]) {
    
    
                    findNextChar(i,j,1);
                }
            }
        }
        if (count>1000000000)
            count=-1;
        return count;
    }
    boolean findNextChar(int x,int y,int c) {
    
    
        boolean found=false,findnext=false;
        if (x-1>=0&&x-1<m&&y-1>=0&&y-1<n) {
    
    
            if (matrix[x-1][y-1]==word[c]) {
    
    
                found=true;
                if (count>1000000000) {
    
    
                    return false;
                }
                if (c==word.length-1) {
    
    
                    count++;
                    findnext=true;
                }
                else {
    
    
                    if (findNextChar(x-1,y-1,c+1))
                        findnext=true;
                }
            }
        }
        if (x-1>=0&&x-1<m&&y>=0&&y<n) {
    
    
            if (matrix[x-1][y]==word[c]) {
    
    
                found=true;
                if (count>1000000000) {
    
    
                    return false;
                }
                if (c==word.length-1) {
    
    
                    count++;
                    findnext=true;
                }
                else {
    
    
                    if (findNextChar(x-1,y,c+1))
                        findnext=true;
                }
            }
        }
        if (x-1>=0&&x-1<m&&y+1>=0&&y+1<n) {
    
    
            if (matrix[x-1][y+1]==word[c]) {
    
    
                found=true;
                if (count>1000000000) {
    
    
                    return false;
                }
                if (c==word.length-1) {
    
    
                    count++;
                    findnext=true;
                }
                else {
    
    
                    if (findNextChar(x-1,y+1,c+1))
                        findnext=true;
                }
            }
        }
        if (x>=0&&x<m&&y-1>=0&&y-1<n) {
    
    
            if (matrix[x][y-1]==word[c]) {
    
    
                found=true;
                if (count>1000000000) {
    
    
                    return false;
                }
                if (c==word.length-1) {
    
    
                    count++;
                    findnext=true;
                }
                else {
    
    
                    if (findNextChar(x,y-1,c+1))
                        findnext=true;
                }
            }
        }
        if (x>=0&&x<m&&y+1>=0&&y+1<n) {
    
    
            if (matrix[x][y+1]==word[c]) {
    
    
                found=true;
                if (count>1000000000) {
    
    
                    return false;
                }
                if (c==word.length-1) {
    
    
                    count++;
                    findnext=true;
                }
                else {
    
    
                    if (findNextChar(x,y+1,c+1))
                        findnext=true;
                }
            }
        }
        if (x+1>=0&&x+1<m&&y-1>=0&&y-1<n) {
    
    
            if (matrix[x+1][y-1]==word[c]) {
    
    
                found=true;
                if (count>1000000000) {
    
    
                    return false;
                }
                if (c==word.length-1) {
    
    
                    count++;
                    findnext=true;
                }
                else {
    
    
                    if (findNextChar(x+1,y-1,c+1))
                        findnext=true;
                }
            }
        }
        if (x+1>=0&&x+1<m&&y>=0&&y<n) {
    
    
            if (matrix[x+1][y]==word[c]) {
    
    
                found=true;
                if (count>1000000000) {
    
    
                    return false;
                }
                if (c==word.length-1) {
    
    
                    count++;
                    findnext=true;
                }
                else {
    
    
                    if (findNextChar(x+1,y,c+1))
                        findnext=true;
                }
            }
        }
        if (x+1>=0&&x+1<m&&y+1>=0&&y+1<n) {
    
    
            if (matrix[x+1][y+1]==word[c]) {
    
    
                found=true;
                if (count>1000000000) {
    
    
                    return false;
                }
                if (c==word.length-1) {
    
    
                    count++;
                    findnext=true;
                }
                else {
    
    
                    if (findNextChar(x+1,y+1,c+1))
                        findnext=true;
                }
            }
        }
        if (found&&findnext)
            return true;
        else return false;
    }
}

  然后,我们实现WordText进行磁盘测试,具体实现如下:

public class WordTest {
    
    
    public static boolean Test1() {
    
    
        WordPath wp=new WordPath();
        String[] grid={
    
    "ABC",
                "FED",
                "GHI"};
        String find="ABCDEFGHI";
        int key=1;
        int result=wp.countPaths(grid,find);
        System.out.println (result);
        return result==key;
    }
    public static boolean Test2() {
    
    
        WordPath wp=new WordPath();
        String[] grid={
    
    "ABC",
                "FED",
                "GAI"};
        String find="ABCDEA";
        int key=2;
        int result=wp.countPaths(grid,find);
        System.out.println (result);
        return result==key;
    }
    public static boolean Test3() {
    
    
        WordPath wp=new WordPath();
        String[] grid={
    
    "ABC",
                "DEF",
                "GHI"};
        String find="ABCD";
        int key=0;
        int result=wp.countPaths(grid,find);
        System.out.println (result);
        return result==key;
    }
    public static boolean Test4() {
    
    
        WordPath wp=new WordPath();
        String[] grid={
    
    "AA",
                "AA"};
        String find="AAAA";
        int key=108;
        int result=wp.countPaths(grid,find);
        System.out.println (result);
        return result==key;
    }
    public static boolean Test5() {
    
    
        WordPath wp=new WordPath();
        String[] grid={
    
    "ABABA",
                "BABAB",
                "ABABA",
                "BABAB",
                "ABABA"};
        String find="ABABABBA";
        int key=56448;
        int result=wp.countPaths(grid,find);
        System.out.println (result);
        return result==key;
    }
    public static boolean Test6() {
    
    
        WordPath wp=new WordPath();
        String[] grid={
    
    "AAAAA",
                "AAAAA",
                "AAAAA",
                "AAAAA",
                "AAAAA"};
        String find="AAAAAAAAAAA";
        int key=-1;
        int result=wp.countPaths(grid,find);
        System.out.println (result);
        return result==key;
    }
    public static boolean Test7() {
    
    
        WordPath wp=new WordPath();
        String[] grid={
    
    "AB",
                "CD"};
        String find="AA";
        int key=0;
        int result=wp.countPaths(grid,find);
        System.out.println (result);
        return result==key;
    }
    public static void main(String[] args) {
    
    
        if (Test1())
            System.out.println ("Test1 OK");
        if (Test2())
            System.out.println ("Test2 OK");
        if (Test3())
            System.out.println ("Test3 OK");
        if (Test4())
            System.out.println ("Test4 OK");
        if (Test5())
            System.out.println ("Test5 OK");
        if (Test6())
            System.out.println ("Test6 OK");
        if (Test7())
            System.out.println ("Test7 OK");
    }
}

  代码执行结果如下

五、球和篮子

1、问题描述

  You have several identical balls that you wish to place in several baskets. Each basket has the same maximum capacity. You are given an int baskets, the number of baskets you have. You are given an int capacity, the maximum capacity of each basket. Finally you are given an int balls, the number of balls to sort into baskets. Return the number of ways you can divide the balls into baskets. If this cannot be done without exceeding the capacity of the baskets, return 0.
Each basket is distinct, but all balls are identical. Thus, if you have two balls to place into two baskets, you could have (0, 2), (1, 1), or (2, 0), so there would be three ways to do this.
  我们翻译成中文为:你有几个同样的球,你希望把它放到几个篮子里。每个篮子有相同的容量。给出int 型的baskets,代表篮子的数量。给出int型的 capacity,代表每个篮子的最大容量。给出int型的balls,表示归类到篮子里的球的数量。返回值是把球归类到篮子里的方式的数量。如果不能完全存放到篮子中,无法划分,返回0。
篮子互不同,所有的球相同。因此,如果2个球放到2个篮子里,你可以采用3种方式,即(0, 2), (1, 1), 或 (2, 0)
  其中的定义以及类名规定如下:
  1、定义——Definition
  2、类名——FillBuskets
  3、方法——countWays
   4、参数——int, int, int
   5、返回——int
  6、方法签名——int countWays(int baskets, int capacity, int balls)
(be sure your method is public)
  7、约束——baskets will be between 1 and 5, inclusive.capacity will be between 1 and 20, inclusive.balls will be between 1 and 100, inclusive.
  8、举例:
  0)、2,20,2, Returns: 3 The example from the problem statement.
  1)、3,20,1,Returns: 3,We have only 1 ball, so we must choose which of the three baskets to place it in.
  2)、3,20,,2,Returns: ,6,We can place both balls in the same basket (3 ways to do this), or one ball in each of two baskets (3 ways to do this).
  3)、1,5,10
Returns: 0,We have more balls than our basket can hold.
  In conclusion,This problem statement is the exclusive and proprietary property of TopCoder, Inc. Any unauthorized use or reproduction of this information without the prior written consent of TopCoder, Inc. is strictly prohibited. ©2003, TopCoder, Inc. All rights reserved.

2、代码实现

  由于此代码我们考虑其利用率,因此,将测试和方法实现分别通过FillBusketBusketTest来实现。
  因此,我们在运行BusketTest之前,首先实现FillBusket,具体实现FillBusket代码如下:

import java.util.*;
public class FillBaskets {
    
    
    int count=0;
    int baskets,capacity,balls;
    int[] bas;
    public int countWays(int baskets, int capacity, int balls) {
    
    
        if (baskets*capacity<balls)
            return 0;
        this.baskets=baskets;
        this.balls=balls;
        if (balls<capacity)
            capacity=balls;
        this.capacity=capacity;
        bas=new int[baskets];

        //从第0个篮子开始放
        putBalls(0);
        return count;
    }

    //
    void putBalls(int n) {
    
    

        //检测是不是到达最后篮子
        if (n==baskets) {
    
    
            if (getSumBalls()==balls)
                count++;
            return;
        }

        //给第n个篮子放球,并且从0->capacity
        //一次轮循的放入
        for (int i=0;i<=capacity;i++) {
    
    
            bas[n]=i;
            putBalls(n+1);
        }
    }
    //得到当前篮子里面所有的球
    int getSumBalls() {
    
    
        int sum=0;
        for (int i=0;i<baskets;i++)
            sum+=bas[i];
        return sum;
    }
}

  然后,我们实现BusketText进行磁盘测试,具体实现如下:

public class BasketTest {
    
    
    public static boolean Test1() {
    
    
        FillBaskets fb=new FillBaskets();
        int baskets=2;
        int capacity=20;
        int balls=2;
        int key=3;
        int result=fb.countWays(baskets,capacity,balls);
        System.out.println (result);
        return result==key;
    }
    public static boolean Test2() {
    
    
        FillBaskets fb=new FillBaskets();
        int baskets=3;
        int capacity=20;
        int balls=1;
        int key=3;
        int result=fb.countWays(baskets,capacity,balls);
        System.out.println (result);
        return result==key;
    }
    public static boolean Test3() {
    
    
        FillBaskets fb=new FillBaskets();
        int baskets=3;
        int capacity=20;
        int balls=2;
        int key=6;
        int result=fb.countWays(baskets,capacity,balls);
        System.out.println (result);
        return result==key;
    }
    public static boolean Test4() {
    
    
        FillBaskets fb=new FillBaskets();
        int baskets=1;
        int capacity=5;
        int balls=10;
        int key=0;
        int result=fb.countWays(baskets,capacity,balls);
        System.out.println (result);
        return result==key;
    }
    public static boolean Test5() {
    
    
        FillBaskets fb=new FillBaskets();
        int baskets=4;
        int capacity=5;
        int balls=10;
        int key=146;
        int result=fb.countWays(baskets,capacity,balls);
        System.out.println (result);
        return result==key;
    }
    public static void main(String[] args) {
    
    
        if (Test1()) {
    
    
            System.out.println ("Test1 Ok");
        }
        if (Test2()) {
    
    
            System.out.println ("Test2 Ok");
        }
        if (Test3()) {
    
    
            System.out.println ("Test3 Ok");
        }
        if (Test4()) {
    
    
            System.out.println ("Test4 Ok");
        }
        if (Test5()) {
    
    
            System.out.println ("Test5 Ok");
        }
    }
}

  具体执行效果如下:

六、扔石头

1、问题描述

  When a stone is thrown across water, sometimes it will land on the water and bounce rather than falling in right away. Suppose that a stone is thrown a distance of n. On each successive bounce it will travel half the distance as the previous bounce (rounded down to the nearest integer). When it can not travel any further, it falls into the water. If, at any point, the stone lands on an obstruction rather than water, it will not bounce, but will simply deflect and fall into the water. Please look at the figure for further clarification (with black, red and green cells representing banks, obstructions and free water respectively). So, if the stone is thrown a distance 7, it will bounce and travel a distance of 3, then finally a distance of 1, having travelled a total distance of 11 (the green path in the figure). If a stone is thrown a distance of 8, it will reach the opposite bank, and if thrown at distances of 2 or 6 it will hit an obstruction during its travel. These are the three red paths in the figure.
  我们翻译成中文为:当石头掉进水中的时候,有时候它会从水面弹起来,假设石头抛出的距离是 n, 每一个后继弹起的距离是前一个距离的一半。(四舍五入到最近的整数)当石头不能再前进时,石头掉进水中,所以石头抛出的距离是7,下一次弹出距离为3,最后一次为1。总共的距离为 11。如果石头抛出的距离是8,
   You are given a String water. An ‘X’ represents an obstruction, while a ‘.’ represents water free from obstruction. You are to return an int representing the maximum distance a stone can travel and finally fall in the water, without hitting any obstructions, and without reaching the opposite bank (going beyond the end of the string). You may choose any initial distance for the throw, which starts from the left side of the string. A distance of 1 is the first character of the string, etc. If no initial throw will result in the stone landing in the water without hitting an obstruction, return 0.
  你被给定一个字符串表示水,一个 ‘X’ 表示一个障碍物,一个 '.'表示水面,你需要返回一个整数,表示石头弹出的最远距离。不可以遇到任何障碍物,也不可以到达对岸。你可以选择一个任意的抛出距离,将从字符串的左端开始,距离 1 表示字符串的第一个字符,等等,如果没有初始抛出,返回 0。
  其中的定义以及类名规定如下:
  1、定义——Definition
  2、类名——SkipStones
  3、方法——maxDistance
   4、参数——String
   5、返回——int
  6、方法签名——int maxDistance(String water)
(be sure your method is public)
  7、约束——disk will contain between 1 and 50 characters, inclusive.Each character of disk will be ‘X’ or ‘.’.size will be between 1 and 50, inclusive.
  8、举例:
  0)、"…X…X…",11, Returns: 11 This is the example from the problem statement.
  1)、"…X…",3,Returns: 3,If it weren’t for the obstruction, we could start with a throw of distance 4, and go a total of 7. But, the best we can do is to throw the stone a distance of 2, and have it skip a distance of 1.
  2)、"…X…X…XXXX.X…",22,Returns: ,22,12 + 6 + 3 + 1 = 22, is the best case.
  3)、“XXXXXXX.XXX.X…”
Returns: 15,Here, an initial throw of 8 is the only way to avoid hitting an obstruction. Notice that the stone finally falls in the water just before reaching the opposite bank.
  In conclusion,This problem statement is the exclusive and proprietary property of TopCoder, Inc. Any unauthorized use or reproduction of this information without the prior written consent of TopCoder, Inc. is strictly prohibited. ©2003, TopCoder, Inc. All rights reserved.

2、代码实现

  由于此代码我们考虑其利用率,因此,将测试和方法实现分别通过SkipStonesStonesTest来实现。
  因此,我们在运行StonesTest之前,首先实现SkipStones,具体实现SkipStones代码如下:

public class SkipStones {
    
    
    int maxDistance(String water) {
    
    
        int n=water.length()/2+1;
        boolean ok=true;
        int temp,result=0;
        char[] str=water.toCharArray();
        for(int i=n;i>0;i--) {
    
    
            ok=true;
            temp=i;
            result=i;
            while (temp>=1) {
    
    
                if (str[result-1]=='X') {
    
    
                    ok=false;
                    break;
                }
                temp=temp/2;
                result+=temp;
            }
            if (ok) {
    
    
                break;
            }
        }
        return result;
    }
}

  然后,我们实现StonesText进行磁盘测试,具体实现如下:

public class StoneTest {
    
    
    public boolean Test1() {
    
    
        SkipStones ss=new SkipStones();
        String water="..X.....X...";
        int result=11;
        return result==ss.maxDistance(water);
    }
    public boolean Test2() {
    
    
        SkipStones ss=new SkipStones();
        String water="...X...";
        int result=3;
        return result==ss.maxDistance(water);
    }
    public boolean Test3() {
    
    
        SkipStones ss=new SkipStones();
        String water="....X....X...XXXX.X.....";
        int result=22;
        return result==ss.maxDistance(water);
    }
    public boolean Test4() {
    
    
        SkipStones ss=new SkipStones();
        String water="XXXXXXX.XXX.X..";
        int result=15;
        return result==ss.maxDistance(water);
    }
    public static void main(String[] args) {
    
    
        StoneTest gt=new StoneTest();
        if (gt.Test1())
            System.out.println ("Test1 ok");
        if (gt.Test2())
            System.out.println ("Test2 ok");
        if (gt.Test3())
            System.out.println ("Test3 ok");
        if (gt.Test4())
            System.out.println ("Test4 ok");
    }
}

  具体执行结果如下:

总结

  我们通过前面的三篇文章,给大家介绍了日常生活中常用的十大算法,主要包括二分查找、分治法、动态规划KMP算法、贪心算法、Prim算法、Kruskal算法Dijstra算法、Floyd算法以及马踏棋盘问题。本篇文章给大家在网上找了一些典型案例帮助大家更好的提升自己在数据结构与算法中的理解。这些案例都是来自google的资料。主要给大家介绍磁盘问题、公交车、画图、矩阵中查找单词路径数、球和篮子以及扔石头等六个问题,并且分别给大家呈现了问题的具体描述以及举了一些例子,然后通过java将其实现。至此,我们数据结构与算法的所有知识全部介绍完毕。其实数据结构与算法是特别重要的,在编程中有至关重要的地位,因此,需要我们特别的掌握。生命不息,奋斗不止,我们每天努力,好好学习,不断提高自己的能力,相信自己一定会学有所获。加油!!!

猜你喜欢

转载自blog.csdn.net/Oliverfly1/article/details/114068494