C#算法问题!!!!!!!生成矩阵

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C#算法问题!!!!!!!生成矩阵相关的知识,希望对你有一定的参考价值。

按三
1 2 3
8 9 4
7 6 5
按四
1 2 3 4
12 13 14 5
11 16 15 6
10 9 8 7

按N

protected void Button1_Click(object sender, EventArgs e)

int nums = int.Parse(this.TextBox1.Text);//输入的数
int[,] sum = new int[nums, nums];//数组声明
int ceng = nums % 2 == 0 ? nums / 2 : nums / 2 + 1;//圈
int ks = 1;//数值
int j = 0;//纵坐标
int k = 0;//横坐标
for (int i = 0; i < ceng; i++)

while (k < nums-i)

sum[j,k] = ks;
ks++;
k++;


k--;
j++;
while (j < nums-i)

sum[j,k] = ks;
ks++;
j++;

j--;
k--;
while (k >=i)

sum[j,k] = ks;
ks++;
k--;

k++;
j--;
while (j > i)

sum[j,k] = ks;
ks++;
j--;

j++;
k++;

string str = "";//输出
for (int i = 0; i < nums; i++)

for (int ii = 0; ii < nums; ii++)

string x = sum[i, ii] > 9 ? sum[i, ii].ToString() : "0" + sum[i, ii].ToString();
str += x+ " ";

str += "<br/>";

Response.Write(str);


输入和输出是WEB的,如果你是winform的就改一下
开始看不懂多看几次
先把矩形画出来,一点一点的移动就看得懂了
费了些时间啊,多加点分啊
参考技术A 这题有意思 我大1用C做过

用于生成层次结构的 C# 算法

【中文标题】用于生成层次结构的 C# 算法【英文标题】:C# algorithm for generating hierarchy 【发布时间】:2010-10-31 04:12:26 【问题描述】:

我有一个如下所示的文本文件:

 Id = 1, ParentId = 0, Position = 0, Title = "root" 
 Id = 2, ParentId = 1, Position = 0, Title = "child 1" 
 Id = 3, ParentId = 1, Position = 1, Title = "child 2" 
 Id = 4, ParentId = 1, Position = 2, Title = "child 3" 
 Id = 5, ParentId = 4, Position = 0, Title = "grandchild 1" 

我正在寻找一种通用的 C# 算法,该算法将以此创建对象层次结构。如果你愿意的话,一个“层次化”功能可以将这些数据转换成一个对象层次结构。

有什么想法吗?

edit 我已经将文件解析为 .NET 对象:

class Node

    public int Id  get; 
    public int ParentId  get; 
    public int Position  get; 
    public string Title  get; 

现在我需要将对象实际排列到对象图中。

【问题讨论】:

你是否已经有了处理这个文本文件解析的代码? 我看不出是什么让 item Id = 5 ... 成为孙子。孙子应该有一个孩子作为其父母,但它与所有其他孩子具有相同的父母。它的 ParentId 不应该是 2、3 或 4 吗?我也不清楚你需要什么“职位”。也许它是指以从左到右的方式对孩子进行排序,您需要明确指定吗? 我会假设 position 属性对每个父母的孩子进行排序。 帮助,我的错,这是一个错字。我已经更新了帖子。 pbz,是的,我已经有了处理文件解析的代码。 【参考方案1】:

非常感谢 Jon 和 mquander - 你们给了我足够的信息来帮助我以适当、通用的方式解决这个问题。这是我的解决方案,一个将对象转换为层次形式的通用扩展方法:

public static IEnumerable<Node<T>> Hierarchize<T, TKey, TOrderKey>(
    this IEnumerable<T> elements, 
    TKey topMostKey, 
    Func<T, TKey> keySelector, 
    Func<T, TKey> parentKeySelector, 
    Func<T, TOrderKey> orderingKeySelector)

    var families = elements.ToLookup(parentKeySelector);
    var childrenFetcher = default(Func<TKey, IEnumerable<Node<T>>>);
    childrenFetcher = parentId => families[parentId]
        .OrderBy(orderingKeySelector)
        .Select(x => new Node<T>(x, childrenFetcher(keySelector(x))));

    return childrenFetcher(topMostKey);

利用这个小节点类:

public class Node<T>

    public T Value  get; private set; 
    public IList<Node<T>> Children  get; private set; 

    public Node(T value, IEnumerable<Node<T>> children)
    
        this.Value = value;
        this.Children = new List<Node<T>>(children);
    

它足够通用,可以解决各种问题,包括我的文本文件问题。漂亮!

****更新****:这是您的使用方法:

// Given some example data:
var items = new[] 

   new Foo() 
   
      Id = 1,
      ParentId = -1, // Indicates no parent
      Position = 0
   ,
   new Foo() 
   
      Id = 2,
      ParentId = 1,
      Position = 0
   ,
   new Foo() 
   
      Id = 3,
      ParentId = 1,
      Position = 1
   
;

// Turn it into a hierarchy! 
// We'll get back a list of Node<T> containing the root nodes.
// Each node will have a list of child nodes.
var hierarchy = items.Hierarchize(
    -1, // The "root level" key. We're using -1 to indicate root level.
    f => f.Id, // The ID property on your object
    f => f.ParentId, // The property on your object that points to its parent
    f => f.Position, // The property on your object that specifies the order within its parent
    );

【讨论】:

你能举个例子如何使用它吗? @Baran 确定。我添加了示例用法。 这甚至适用于动态对象!正是我需要的!谢谢!【参考方案2】:

嗯...我不太明白它是如何工作的。 2 和 5 怎么会有 parent=1,position=0? 5 应该有父 2、3 还是 4?

好的,这个新版本遍历所有节点三遍:

加载所有节点并将它们放入 a 地图中 将每个节点与其父节点关联 按位置对每个节点的子节点进行排序

它没有很好地封装,很好地检查错误等 - 但它可以工作。

using System;
using System.Collections.Generic;
using System.IO;

public class Node

    private static readonly char[] Braces = "".ToCharArray();
    private static readonly char[] StringTrim = "\" ".ToCharArray();

    public Node Parent  get; set; 
    public int ParentId  get; private set; 
    public int Id  get; private set; 
    public string Title  get; private set; 
    public int Position  get; private set; 
    private readonly List<Node> children = new List<Node>();
    public List<Node> Children  get  return children;  

    public static Node FromLine(string line)
    
        Node node = new Node();
        line = line.Trim(Braces);
        string[] bits = line.Split(',');
        foreach (string bit in bits)
        
            string[] keyValue = bit.Split('=');
            string key = keyValue[0].Trim();
            string value = keyValue[1].Trim();
            switch (key)
            
                case "Id":
                    node.Id = int.Parse(value);
                    break;
                case "ParentId":
                    node.ParentId = int.Parse(value);
                    break;
                case "Position":
                    node.Position = int.Parse(value);
                    break;
                case "Title":
                    node.Title = value.Trim(StringTrim);
                    break;
                default:
                    throw new ArgumentException("Bad line: " + line);
            
        
        return node;
    

    public void Dump()
    
        int depth = 0;
        Node node = this;
        while (node.Parent != null)
        
            depth++;
            node = node.Parent;
        
        Console.WriteLine(new string(' ', depth * 2) + Title);
        foreach (Node child in Children)
        
            child.Dump();
        
    


class Test
       
    static void Main(string[] args)
    
        var dictionary = new Dictionary<int, Node>();

        using (TextReader reader = File.OpenText("test.txt"))
        
            string line;
            while ((line = reader.ReadLine()) != null)
            
                Node node = Node.FromLine(line);
                dictionary[node.Id] = node;
            
        
        foreach (Node node in dictionary.Values)
        
            if (node.ParentId != 0)
            
                node.Parent = dictionary[node.ParentId];
                node.Parent.Children.Add(node);
            
        

        foreach (Node node in dictionary.Values)
        
            node.Children.Sort((n1, n2) =>
                               n1.Position.CompareTo(n2.Position));
        

        Node root = dictionary[1];
        root.Dump();
    

示例文本文件:

 Id = 5, ParentId = 4, Position = 0, Title = "grandchild 1" 
 Id = 2, ParentId = 1, Position = 0, Title = "child 1" 
 Id = 4, ParentId = 1, Position = 2, Title = "child 3" 
 Id = 3, ParentId = 1, Position = 1, Title = "child 2" 
 Id = 1, ParentId = 0, Position = 0, Title = "root" 

输出:

root
  child 1
  child 2
  child 3
    grandchild 1

【讨论】:

乔恩,您的代码不会读取文本文件。您神奇地将文本文件(数据)转换为源代码。那种消除或忽略了一半的问题。 @Cheeso:这就是为什么我要求你在问题的 cmets 中指定是否也需要这个。解析文本文件是一个完全不同的问题,对我来说,这个洞闻起来像家庭作业。 @Cheeso:我以为你可以做到这一点。文本文件真的是那种格式吗?字符串是如何转义的?我将编辑答案以使其完全解析问题中的格式,但我们确实需要更多信息。 好的,我已经放入了一个 very 原始解析器,它假设没有什么有趣的东西,比如字符串转义等。我仍然忽略了 Position,假设事情会在正确的顺序,我仍然假设父母在孩子之前。哦,我仍然认为您提供的示例中有错字……但除此之外,它确实有效。 乔恩,我的错,这是一个错字。我已经更新了帖子,以便 ID 5 是正确的孙子。【参考方案3】:

解析完文件后,您可以按照blog 了解如何使用 LINQ 将对象组装成层次结构。

【讨论】:

很有趣,但似乎 Omer Van Kloeten 的实现并不关心父母内部的排序。【参考方案4】:

我假设您的示例错误地为对象 #5 提供了错误的父 ID。这应该涵盖它。注意事项:假设“最顶层”节点的父 ID 始终为零。忽略最终不是从最顶层节点下降的任何节点。如果出现重复 ID,行为会很奇怪。

public class FlatObj

    public int Id;
    public int ParentId;
    public int Position;
    public string Title;


public class Node

    public int ID;
    public string Title;
    public IList<Node> Children;

    public Node(FlatObject baseObject, IList<Node> children)
    
        this.ID = baseObject.Id;
        this.Title = baseObject.Title;
        this.Children = children;
    


public static Node CreateHierarchy(IEnumerable<FlatObject> objects)

    var families = objects.ToLookup(x => x.ParentId);
    var topmost = families[0].Single();

    Func<int, IList<Node>> Children = null;

    Children = (parentID) => families[parentID]
        .OrderBy(x => x.Position)
        .Select(x => new Node(x, Children(x.Id))).ToList();

    return new Node(topmost, Children(topmost.Id));


public static void Test()

    List<FlatObj> objects = new List<FlatObj> 
    new FlatObj  Id = 1, ParentId = 0, Position = 0, Title = "root" ,
    new FlatObj  Id = 2, ParentId = 1, Position = 0, Title = "child 1" ,
    new FlatObj  Id = 3, ParentId = 1, Position = 1, Title = "child 2" ,
    new FlatObj  Id = 4, ParentId = 1, Position = 2, Title = "child 3" ,
    new FlatObj  Id = 5, ParentId = 2, Position = 0, Title = "grandchild" ;

    var nodes = CreateHierarchy(objects);

【讨论】:

我认为你在两个方面没有抓住重点。您专注于文本文件中某一行的 ParentId。让我们暂时假设原始问题中有错字。无论如何,问题仍然存在 - 如何从这种数据中水合对象图。您提供的答案使用看起来像文本文件的源代码。 ???这相当于一半的答案。你完全忽略了解析文件的问题。对您来说,这似乎很简单,但它并非微不足道。 我认为他的问题是假设文件已经被解析为类似于我的 FlatObj 的某个对象,并且他正在向我们展示文件内容的抽象表示。 mquander 是正确的,我的问题假设文本文件已经被解析为一些对象数据。我将更新问题以澄清这一点。 mquander,感谢您的解决方案,我会试一试。如果结果很好,我会将其标记为正确答案。【参考方案5】:
class Node 
    public int Id  get;set;  
    public int ParentId  get;set;  
    public int Position  get;set;  
    public string Title  get;set;  
    public IEnumerable<Node> Children  get; set; 

    public override string ToString()  return ToString(0); 
    public string ToString(int depth) 
        return "\n" + new string(' ', depth * 2) + Title + (
            Children.Count() == 0 ? "" :
            string.Join("", Children
                .Select(node => node.ToString(depth + 1))
                .ToArray()
            );
    

class Program 
    static void Main(string[] args) 
        var data = new[] 
            new Node Id = 1, ParentId = 0, Position = 0, Title = "root" ,
            new Node Id = 2, ParentId = 1, Position = 0, Title = "child 1" ,
            new Node Id = 3, ParentId = 1, Position = 1, Title = "child 2" ,
            new Node Id = 4, ParentId = 1, Position = 2, Title = "child 3" ,
            new Node Id = 5, ParentId = 3, Position = 0, Title = "grandchild 1" 
        ;
        Func<Node, Node> transform = null;
        transform = node => new Node 
            Title = node.Title,
            Id = node.Id,
            ParentId = node.ParentId,
            Position = node.Position,
            Children = (
                from child in data
                where child.ParentId == node.Id
                orderby child.Position
                select transform(child))
        ;
        Console.WriteLine(transform(data[0]));
    

结果:

root
  child 1
  child 2
    grandchild 1
  child 3

【讨论】:

【参考方案6】:

你确定最后一行的 ParentID 是 1 吗?标题是孙子,但如果我没看错的话,它会是“根”的孩子。

【讨论】:

【参考方案7】:

这是@baran 要求的示例:

var lHierarchicalMenuItems = lMenuItemsFromDB.Hierarchize(0, aItem => aItem.Id, aItem => aItem.ParentId, aItem => aItem.Position);

【讨论】:

以上是关于C#算法问题!!!!!!!生成矩阵的主要内容,如果未能解决你的问题,请参考以下文章

数据结构与算法:终于可以用三种语言(C,C#,JavaScript)把图的广度优先遍历讲清楚了(推荐收藏)

数据结构与算法:终于可以用三种语言(C,C#,JavaScript)把图的广度优先遍历讲清楚了(推荐收藏)

生成树计数算法

用于生成层次结构的 C# 算法

优化的OCR黑白像素算法

最小生成树Kruskal算法(邻接矩阵和邻接表)