算法小玩意
N皇后问题
N*N的棋盘上摆上N个皇后,使皇后不会相互攻击。
public class NQueenPuzzle 
{    
    private readonly int queenAmount;    
    private readonly int[] xLocations;
private int solutionCount = 0;
    public NQueenPuzzle(int n)   
    {    
        queenAmount = n;    
        xLocations = new int[queenAmount];    
    }
    //使用栈求解   
    public void Solve_stack()    
    {    
        Stack<int> lastPos = new Stack<int>(queenAmount);    
        lastPos.Push(-1);    
        while (lastPos.Count > 0)    
        {    
            var s = lastPos.Pop();    
            for (int i = s + 1; i < queenAmount; i++)    
            {    
                var k = lastPos.Count;    
                xLocations[k] = i;    
                if (this.Validate(k))    
                {    
                    if (k == queenAmount - 1)    
                    {    
                        this.PrintResult();    
                        return;    
                    }
                    lastPos.Push(i);   
                    lastPos.Push(-1);    
                    break;    
                }    
            }    
        }    
    }
    //使用递归求解   
    public void Solve()    
    {    
        Stopwatch sw = Stopwatch.StartNew();    
        this.Locate(0);    
        Console.WriteLine("time cost to solve puzzle: {0:g}", sw.Elapsed);
        if (solutionCount == 0)   
        {    
            Console.WriteLine("No result for puzzle with {0} queen", queenAmount);    
        }    
        else    
        {    
            Console.WriteLine("total {0} result for puzzle with {0} queen", solutionCount, queenAmount);    
        }    
    }
    private void Locate(int k)   
    {    
        if (k == queenAmount)    
        {    
            solutionCount++;    
            Console.WriteLine("*** result {0} *****", this.solutionCount);    
            this.PrintResult();    
            return;    
        }
   
        for (int i = 0; i < queenAmount; i++)    
        {    
            xLocations[k] = i;
            if (this.Validate(k))   
            {    
                Locate(k + 1);    
            }    
        }    
    }
    private void PrintResult()   
    {    
        for (int i = 0; i < this.queenAmount; i++)    
        {    
            for (int j = 0; j < this.queenAmount; j++)    
            {    
                Console.Write(j == this.xLocations[i] ? "x " : "- ");    
            }
            Console.WriteLine();   
        }
        Console.WriteLine();   
    }
    private bool Validate(int k)   
    {    
        bool valid = true;    
        for (int j = 0; j < k; j++)    
        {    
            if (this.xLocations[j] == this.xLocations[k] || Math.Abs(this.xLocations[j] - this.xLocations[k]) == Math.Abs(j - k))    
            {    
                valid = false;    
                break;    
            }    
        }    
        return valid;    
    }    
}
使用下面的方法输出8皇后解决方案。
NQueenPuzzle puzzle = new NQueenPuzzle(8);    
puzzle.Solve(); 
0-1背包问题
一组宝石,价值对应values,重量对应weight,一个背包最大承重capcity,求怎样选择宝石,可使背包装下价值最多?
public class BagPack0_1   
{    
    private int[] values;
private int[] weight;
private int capcity;
private int n;
    public BagPack0_1(int[] v, int[] w, int c)   
    {    
        values = v;    
        weight = w;    
        capcity = c;    
        n = values.Length;    
    }
    public void Solve()   
    {    
        int[,] M = new int[n + 1, capcity + 1];
        for (int i = 1; i <= n; i++)   
        {    
            for (int j = 1; j <= capcity; j++)    
            {    
                if (j < weight[i - 1])    
                {    
                    M[i, j] = M[i - 1, j];    
                }    
                else    
                {    
                    M[i, j] = Math.Max(M[i - 1, j], M[i - 1, j - weight[i - 1]] + values[i - 1]);    
                }    
            }    
        }
   
        Console.WriteLine("max values:{0}", M[n, capcity]);
        this.ShowResult(M, n, capcity);   
    }
    private void ShowResult(int[,] M, int i, int j)   
    {    
        if (i == 0 || j == 0)    
        {    
            return;    
        }    
        if (j >= weight[i - 1] && M[i, j] == M[i - 1, j - weight[i - 1]] + values[i - 1])    
        {    
            this.ShowResult(M, i - 1, j - weight[i - 1]);    
            Console.WriteLine("index:{0}, weight:{1}, value:{2} selected ", i, weight[i - 1], values[i - 1]);    
        }    
        else    
        {    
            this.ShowResult(M, i - 1, j);    
        }    
    }
}
测试用例:
int[] w = { 1, 3, 4, 5, 6, 2, 4, 8, 10 };   
int[] v = { 4, 2, 1, 10, 12, 2, 30, 40, 10 };    
int capacity = 36;    
BagPack0_1 bp = new BagPack0_1(v, w, capacity);
bp.Solve();
最大子串问题
两个数组A、B,求最大子串。   
public class MaxSubString<T>    
{    
    private T[] A;
private T[] B;
private int m;
private int n;
    public MaxSubString(T[] A, T[] B)   
    {    
        this.A = A;    
        this.B = B;    
        m = A.Length + 1;    
        n = B.Length + 1;    
    }
    //最大子串引申问题。两个字符串最长相同子串。   
    public void Solve_continuous()    
    {    
        var M = new int[m, n];    
        int maxLen = 0;    
        int pos = 0;
        for (int i = 1; i < m; i++)   
        {    
            for (int j = 1; j < n; j++)    
            {    
                M[i, j] = object.Equals(A[i - 1], B[j - 1]) ? M[i - 1, j - 1] + 1 : 0;    
                if (M[i, j] > maxLen)    
                {    
                    maxLen = M[i, j];    
                    pos = i;    
                }    
            }    
        }
Console.WriteLine("maxLen is:{0}", maxLen);
        for (int i = maxLen; i > 0; i--)   
        {    
            Console.Write(A[pos - i].ToString() + ",");    
        }    
    }
    //数组M记录最大子串长度   
    public void Solve2()    
    {    
        var M = new int[m, n];
        for (int i = 1; i < m; i++)   
        {    
            for (int j = 1; j < n; j++)    
            {    
                if (object.Equals(A[i - 1], B[j - 1]))    
                {    
                    M[i, j] = M[i - 1, j - 1] + 1;    
                }    
                else    
                {    
                    if (M[i - 1, j] > M[i, j - 1])    
                    {    
                        M[i, j] = M[i - 1, j];    
                    }    
                    else    
                    {    
                        M[i, j] = M[i, j - 1];    
                    }    
                }    
            }    
        }
        this.ShowResult2(M, m - 1, n - 1);   
        Console.WriteLine();    
    }
    private void ShowResult2(int[,] M, int i, int j)   
    {    
        if (i == 0 || j == 0)    
        {    
            return;    
        }
        if (M[i, j] == M[i - 1, j])   
        {    
            this.ShowResult2(M, i - 1, j);    
        }    
        else if (M[i, j] == M[i, j - 1])    
        {    
            this.ShowResult2(M, i, j - 1);    
        }    
        else    
        {    
            this.ShowResult2(M, i - 1, j - 1);    
            Console.Write("," + A[i - 1]);    
        }    
    }
    //使用辅助数组S,记录数组元素是否是最大子串成员   
    public void Solve1()    
    {    
        int[,] M = new int[m, n];    
        int[,] S = new int[m, n];//1left,2up,3select
        for (int i = 0; i < m; i++)   
        {    
            M[i, 0] = 0;    
        }    
        for (int i = 0; i < n; i++)    
        {    
            M[0, i] = 0;    
        }
        for (int i = 1; i < m; i++)   
        {    
            for (int j = 1; j < n; j++)    
            {    
                if (object.Equals(A[i - 1], B[j - 1]))    
                {    
                    M[i, j] = M[i - 1, j - 1] + 1;    
                    S[i, j] = 3;    
                }    
                else    
                {    
                    if (M[i - 1, j] > M[i, j - 1])    
                    {    
                        M[i, j] = M[i - 1, j];    
                        S[i, j] = 1;    
                    }    
                    else    
                    {    
                        M[i, j] = M[i, j - 1];    
                        S[i, j] = 2;    
                    }    
                }    
            }    
        }
Console.WriteLine("Max sub list count:{0}", M[m - 1, n - 1]);
        ShowResult(S, m - 1, n - 1);   
        Console.WriteLine();    
    }
    private void ShowResult(int[,] S, int i, int j)   
    {    
        if (i == 0 || j == 0)    
        {    
            return;    
        }
        if (S[i, j] == 3)   
        {    
            ShowResult(S, i - 1, j - 1);    
            Console.Write("," + A[i - 1]);    
        }    
        else if (S[i, j] == 1)    
        {    
            ShowResult(S, i - 1, j);    
        }    
        else if (S[i, j] == 2)    
        {    
            ShowResult(S, i, j - 1);    
        }    
    }
}
测试:
int[] A = new[] { 1, 2, 3, 4 };   
int[] B = { 1, 2, 1, 2, 3, 4 };
MaxSubString<int> mss = new MaxSubString<int>(A, B);   
mss.Solve1();
                    
                
                
            
        
浙公网安备 33010602011771号