[翻译]asp.net 1.x/2.0中的高级列表控件

RPGMaker MV 插件基础02:插件的参数定义 回顾上一节,我们创建了一个test.js文件,对应的插件名称就是test,我们定义了插件的名称,作者与帮助信息,这节讲一下如何定义插件的参数并且通过js代码获得参数 阅读详情
原文地址: http://aspalliance.com/1071_Smart_ListControl_in_ASPNET_1x20
[原文源码下载]
[译者改后源码下载]


[翻译]asp.net 1.x/2.0中的高级列表控件


原文发布日期:2006.11.16
作者:Bilal Haidar
翻译:webabcd


摘要
本文中Bilal Haidar将告诉你如何在asp.net 1.x/2.0下开发一个高级列表控件,使它可以在客户端保存其自身每一项的变化。


文章内容
介绍
解决方案
类的实现
实现IPostBackDataHandler接口
如何使用新控件
下载
结论


介绍
在 asp.net 中,当aspx页上的一个列表控件发生回发事件到服务端时,这个列表控件的功能如下。

无论是依靠WebForm中的Forms还是QueryString方式传值,列表控件中的各个项都不会回发至服务端。

只有列表控件中被选中的值才会在一个回发事件里把值传递到服务端,这说明一个被选中的项可以在服务端被侦测到。

当这个响应返回到客户端时,列表控件中的各个项会从视图状态检索到。

以上这个事实暴露出了一些列问题,特别是当你在客户端作一些变化的时候。比如,在列表控件中删除或新增项。伴随着页面回发至服务端,列表控件在客户端所做的这些改变都不会被服务端侦测到。无论你做过什么改变,再一次回发之后,都会消失不见,列表控件又会重新从视图状态中加载各个项。

在一些程序中会有对列表控件添加项和删除项的要求。想象一下,在页面上有两个列表控件,然后又一些按钮可以让两个列表控件互相移动各自的项。举个例子,有两个ListBox分别放置已完成和未完成的任务,当一个任务完成时,你可以把这个任务从未完成的ListBox中转移到已完成的ListBox中,但是稍后你会发现,你没有把那个已完成的任务从未完成的ListBox转移出来。

为了让你的webform有一个更好的表现,比如像实现上面所说的功能,我们需要用一些客户端的javascript来代替某些服务端的操作。但是,作为一个列表控件,ListBox将会有无法保存其各个项变化的问题,因为这是在asp.net里ListBox和任何其他的列表控件的默认的行为。

本文的用意就是解决这个问题,使列表控件的各个项的变化可以被保存,可以被服务端侦测到。

我们用ListBox控件做例子,在aps.net里的其他列表控件也都可以使用同样的技术使其转化为高级列表控件。


解决方案
这部分我们将在一个实际的方案中去解决问题。我们需要在新的控件中加入两个隐藏字段。

第一个隐藏字段的命名规则如下:
ListBoxID + "_ADDED"
上面这个字段将用来保存ListBox控件的增加项。
假设要增加项:
Text = "First Item"
Value = "1"
一个新项将被增加到这个隐藏字段中:
Text|Vale
例,上面的项增加后该隐藏字段则增加:
First Item|1
任意增加项都将被加到这个隐藏字段中
Item1|Value1,Item2|Value2
每一项以何种格式添加到隐藏字段中是有非常严格的要求的。正像你从上面看到的那样,每一项都要用“,”分隔开,如此就能把每一个单独的项作为一个新的ListItem添加到ListBox控件中。

第二个隐藏字段的命名规则如下:
ListBoxID + "_REMOVED"
上面这个字段将用来保存ListBox控件的删除项的value。稍后我们将在服务端看到ListBox控件被选中的值和被删除的值,从而反应出客户端的行为和变化。

除了上面所提及的解决方案的一部分,我们还将实现IPostBackDataHandler接口,这个接口有两个方法,LoadPostData和RaisePostDataChangedEvent。本文将对这个接口的实现做简要论述。


类的实现
当我们要改善ListBox控件之后,首先要做的就是要继承ListBox类。目标是给这个类增加实现客户端各个项变化的功能。

下面的代码说明了如何继承ListBox类。

列表1

public   class  xListBox : ListBox
{
}

ListBox控件所有的公共属性和方法都将可以像以前一样被使用。有一个要引起注意的方法,就是OnPreRender,这个方法将被override以增加前面所说的两个隐藏字段。

OnPreRender如下:

列表2
protected   override   void  OnPreRender(EventArgs e)
{
  
base.OnPreRender(e);
 
  
// 将控件注册为要求在页回发至服务器时进行回发处理的控件。
  if (Page != null)
    Page.RegisterRequiresPostBack(
this);
 
  
// 注册保存增加项的隐藏字段
  Page.RegisterHiddenField(this.HFItemsAdded, "");
 
  
// 注册保存删除项的隐藏字段
  Page.RegisterHiddenField(this.HFItemsRemoved, "");
 
  
// 注册包含在UtilMethods里的一段客户端javascript
  if (!Page.IsClientScriptBlockRegistered("UtilMethods"))
    Page.RegisterClientScriptBlock(
"UtilMethods", jsScript);
}

当你要写自己自定义控件的时候,几乎每次都要override基类的OnPreRender,这是通过基类增加功能,保存代码的通常做法。

任何客户端代码,像javascript或者任何注册在父控件的控件,都应该在控件的这个生命周期(PreRender)中实现。

注意,我们已经在关键字UtilMethods注册了一段javascript代码。这段代码提供了两个客户端函数,主要是AddItemToList和RemoveItemFromList。这些函数使用了前面所提到的两个隐藏字段。它们已经实现了这样一个功能,就是两个隐藏字段保持同步,以使两个隐藏字段不会出现同一项。

这段javascript代码出示如下:

列表3
//  增加新项到 ListBoxID_ADDED 隐藏字段中
function  AddListItem(listName, text, value)
{
  
var hiddenField = GetHiddenField(listName.id + '_ADDED');
 
  
if (hiddenField != null)
  
{
    
// 加一个分隔符
    var tmp = hiddenField.value;
    
if (tmp != '')
      hiddenField.value 
+= ',';
 
    
// 加一项到隐藏字段
    hiddenField.value += text + '|' + value;
 
    
// 如果删除字段中有这项则在删除字段中删之
    var removeHiddenField = GetHiddenField(listName.id + '_REMOVED');
    
if (removeHiddenField != null)
    
{
      
var removedItems = removeHiddenField.value.split(',');
      removeHiddenField.value 
= '';
      
for (var i = 0; i < removedItems.length; i++)
      
{
        
if (value != removedItems[i])
        
{
          
// 加一个分隔符
          var tmp1 = removeHiddenField.value;
          
if (tmp1 != '')
            removeHiddenField.value 
+= ',';
 
          removeHiddenField.value 
+= removedItems[i];
        }

      }

    }

  }

}

 
//  将删除项的value增加到 ListBoxID_REMOVED 隐藏字段中
function  RemoveListItem(listName, value)
{
  
var hiddenField = GetHiddenField(listName.id + '_REMOVED');
 
  
if (hiddenField != null)
  
{
    
// 加一个分隔符
    var tmp = hiddenField.value;
    
if (tmp != '')
      hiddenField.value 
+= ',';
 
    hiddenField.value 
+= value;
 
    
// 如果增加字段中有这项则在增加字段中删之
    var addHiddenField = GetHiddenField(listName.id + '_ADDED');
    
if (addHiddenField != null)
    
{
      
var addedItems = addHiddenField.value.split(',');
      addHiddenField.value 
= '';
      
for (var i = 0; i < addedItems.length; i++)
      
{
        
if (addedItems[i].match(value) == null)
        
{
          
// 加一个分隔符
          var tmp1 = addHiddenField.value;
          
if (tmp1 != '')
            addHiddenField.value 
+= ',';
 
          addHiddenField.value 
+= addedItems[i];
        }

      }

    }

  }

}

 
//  在页中找到某个隐藏字段
function  GetHiddenField(fieldName)
{
  
var hiddenField;
  hiddenField 
= document.getElementById(fieldName);
 
  
if (hiddenField != null)
    
return hiddenField;
 
  
return null;
}
 

上面这段代码已经写到了OnPreRender方法中,稍后当我们讨论“如何使用新控件”的时候再和大家说明如何调用这些方法。

这有三个方法:
AddListItem
RemoveListItem
GetHiddenField

AddListItemt通过取得用于保存增加项的隐藏字段的ID设置该隐藏字段所包含的ListBox控件的增加项。新增加的项将会按照(Text|Value)的格式增加到用于保存增加项的隐藏字段中。如果其中有的项在用于保存删除项的隐藏字段中,则在用于保存增加项的隐藏字段中删之。这保证了删除项保存在用于保存删除项的隐藏字段,增加项保存在用于保存增加项的隐藏字段的正确性。

RemoveListItem通过取得用于保存删除项的隐藏字段的ID设置该隐藏字段所包含的ListBox控件的删除项。被删除的项的value将会保存到用于保存删除项的隐藏字段中,每一项用分隔符“,”标记。每次删除都会检查一次用于保存增加项的隐藏字段以保证用于保存删除项的隐藏字段和用于保存增加项的隐藏字段的值不会有冲突。

最后的GetHiddenField是一个在网页中找到隐藏字段的常用方法。


实现IPostBackDataHandler接口
IPostBackDataHandler接口包含两个主要方法:
IPostBackDataHandler.RaisePostDataChangedEvent
IPostBackDataHandler.LoadPostData

当你继承了一个控件后怎么实现这两个方法呢?

虽然这个问题不是本文的重点,但我们仍然会简要的介绍一下继承自这个接口的控件如何实现这两个方法。

当一个回发事件发生时,页面将重新创建控件。最开始创建的是页面的主控件,然后是其子控件,再然后是子控件的子控件……

每个控件都将被检查是否实现了某些接口。IPostBackDataHandler接口就是其中之一。如果这个接口被实现了,就意味着上面所提及的两个方法被实现了。

这些方法通常被实现去处理每一次的回发数据。默认的,aps.net中的ListBox控件将实现以上的两个方法。

LostPostData实现的功能是侦测ListBox控件某一被选中的索引,或者在ListBox控件的SelectionMode被设置成Multiple的时候侦测ListBox控件所有被选中的索引。

我们将这么实现LoadPostData方法。首先要保留原来方法的默认行为,即侦测被选中的索引,然后我们还要得到在上面所提到的两个隐藏字段中被保存的数据。

被保存的数据分别在两个隐藏字段中,“删除隐藏字段”保存被删除的项的value,“增加隐藏字段”保存增加项的text和value。

以下代码显示了LoadPostData是如何被实现的。

列表4
         bool  IPostBackDataHandler.LoadPostData( string  postDataKey, NameValueCollection postCollection)
        
{
            
// 处理被选中的value
            string[] postedItems = postCollection.GetValues(postDataKey);
            
bool returnValue = false;

            
// 如果没有被选中的项
            if (postedItems == null)
            
{
                
if (this.SelectedIndex != -1)
                
{
                    returnValue 
= true;
                }


                
// 处理客户端的变化去
                goto HandleClientChanges;
            }


            
// 如果SelectionMode是Single模式
            if (this.SelectionMode == ListSelectionMode.Single)
            
{
                
if (postedItems != null)
                
{
                    
// 处理postedItems的第一项,其是被选中的
                    int index = this.FindByValueInternal(postedItems[0]);
                    
if (this.SelectedIndex != index)
                    
{
                        
// 发生变化了
                        this.SelectedIndex = index;
                        returnValue 
= true;
                    }

                }

            }


            
// 否则SelectionMode是Multiple模式
            
// 新的被选中的Length
            int numberOfItemsSelected = postedItems.Length;

            
// 原来的被选中的索引集合
            ArrayList oldSelectedItems = this.SelectedIndicesInternal;

            
// 新集合,Length为新的被选中的Length
            ArrayList currentlySelectedItems = new ArrayList(numberOfItemsSelected);

            
// 把所有新的被选中的value塞进来
            for (int i = 0; i < numberOfItemsSelected; i++)
            
{
                currentlySelectedItems.Add(
this.FindByValueInternal(postedItems[i]));
            }


            
// 原来被选中的Length
            int numberOfSelectedItems = 0;
            
if (oldSelectedItems != null)
            
{
                numberOfSelectedItems 
= oldSelectedItems.Count;
            }


            
// 原来的和新的被选中的是否相同
            if (numberOfItemsSelected == numberOfSelectedItems)
            
{
                
for (int j = 0; j < numberOfItemsSelected; j++)
                
{
                    
int oldSelect = Convert.ToInt32(currentlySelectedItems[j]);
                    
int currentSelect = Convert.ToInt32(oldSelectedItems[j]);

                    
if (oldSelect != currentSelect)
                    
{
                        
// 标记该项被选中
                        this.Items[j].Selected = true;
                        returnValue 
= true;
                    }

                }

            }

            
else
            
{
                
// 原来的和新的被选中的发生了变化(原来的和新的被选中的Length不同就肯定是发生变化了)
                returnValue = true;
            }


            
// 有变化,重新设置Selected(设为新的)
            if (returnValue)
            
{
                
this.SelectInternal(currentlySelectedItems);
            }



        
// 这部分处理客户端的变化(项的增减)
        HandleClientChanges:

            
// 从项集合中删除项
            
// 处理客户端删除项操作
            string itemsRemoved = postCollection[this.HFItemsRemoved];
            
string[] itemsRemovedCol = itemsRemoved.Split(',');
            
if (itemsRemovedCol != null)
            
{
                
if ((itemsRemovedCol.Length > 0) && (itemsRemovedCol[0] != ""))
                
{
                    
for (int i = 0; i < itemsRemovedCol.Length; i++)
                    
{
                        ListItem itemToRemove 
= this.Items.FindByValue(itemsRemovedCol[i]);

                        
// 从集合中删除该项
                        Items.Remove(itemToRemove);
                    }

                    returnValue 
= true;
                }

            }


            
// 处理客户端增加项操作
            string itemsAdded = postCollection[this.HFItemsAdded];
            
string[] itemsCol = itemsAdded.Split(',');
            
if (itemsCol != null)
            
{
                
if ((itemsCol.Length > 0) && (itemsCol[0] != ""))
                
{
                    
// counter 用于确定返回值是什么
                    int counter = -1;
                    
for (int i = 0; i < itemsCol.Length; i++)
                    
{
                        
string buf = itemsCol[i];
                        
string[] itemsTokens = buf.Split('|');

                        
// 通过value检查是否已集合中已有该value
                        ListItem it = this.Items.FindByValue(itemsTokens[1]);
                        
if (it == null)
                        
{
                            
string text = itemsTokens[0];
                            
string id = itemsTokens[1];
                            ListItem item 
= new ListItem(text, id);
                            Items.Add(item);

                            
// 更新 counter
                            counter++;
                        }

                    }

                    returnValue 
= counter > -1 ? true : false;
                }

            }


            
return returnValue;
        }

这段代码首先实现了原来asp.net下的ListBox控件的LoadPostData方法

第二部分实现了通过用于保存删除项的隐藏控件存储的value从ListBox中删除项的功能

第三部分实现了通过用于保存增加项的隐藏控件存储的text|value从ListBox中增加项的功能

我们没有更多的说RaisePostDataChangedEvent方法,因为它的实现比较简单。

列表5
void  IPostBackDataHandler.RaisePostDataChangedEvent()
{
  OnSelectedIndexChanged(EventArgs.Empty);
}

这个方法什么时候被调用呢?通过LoadPostData返回来的Boolean值来判断是否触发该方法。如果返回值为true,则证明被选中的值发生了变化,所以需要调用OnSelectedIndexChanged这个方法。

另外,如果LoadPostData返回的值为false,则证明选中的值没有发生变化,所以不用调用OnSelectedIndexChanged方法。

通过以上所说的,我们已经完成了一高级ListBox控件。接下来的部分,我们将看到一个例子来说明如何在webform中使用这个控件,如何调用前面所提及的那两个javascript函数。


如何使用新控件
在这一部分中,我们演示一个包含新的ListBox控件的webform,这个新的ListBox控件就是我们上面所创建的那个控件。

增加一个按钮来处理从ListBox中删除项的操作。

增加两个textbox控件,让用户输入为了插入ListBox里的text和value。另外,再增加一个按钮使新输入的项可以被插到ListBox中。

上面这些按钮都是客户端按钮,因此,ListBox的内部的各个项可以在客户端使用javascript来操作。

最后,一个服务端的按钮用于强制回发到服务端,同时ListBox各个项的变化都将被保存。

这个webfrom如下图所示。
图1

当你在ListBox中选择了一项,按下删除按钮时,所选择的项将从ListBox中删除,同时被删除的项的value将被添加到用于保存删除项的隐藏字段中。实现这个功能的代码如下。

列表6
     function  RemoveItem()
    
{
        
// 得到ListBox
        var sourceListBox = document.getElementById('ListBox1');
        
        
// 检查ListBox是否为null
        if (sourceListBox != null)
        
{
            
// 获得被选项的value
            var selectedValue = sourceListBox.options[sourceListBox.options.selectedIndex].getAttribute("value");
            
            
// 从ListBox中删除该项
            sourceListBox.remove(sourceListBox.options.selectedIndex);
            
            
// 调用我们的ListBox输出到客户端的函数
            RemoveListItem(sourceListBox, selectedValue);            
        }

    }

你可以看到,这些代码已经有了自身的注释。当我们从ListBox中删除项的时候,我们已经可以检测到被选项了。最后,我们示例了一下如何调用新的ListBox中的那些客户端方法。

ListBox的ID和要被删除的项的value作为RemoveListItem需要的参数。

当你要向ListBox中增加项的时候,你只要简单的在两个textbox输入text和value,然后按“增加新项”按钮即可。这个按钮所触发的客户端代码如下:

列表7
     function  AddItem()
    
{
        
// 得到ListBox
        var sourceListBox = document.getElementById('ListBox1');
        
var txt_text = document.getElementById('TextBox1');
        
var txt_value = document.getElementById('TextBox2');
        
        
// 检查ListBox是否为null
        if ((sourceListBox != null) && (txt_text != null) && (txt_value != null))
        
{
            
// 创建一个新项
            var newOption = new Option(); 
            newOption.text 
= txt_text.value;
            newOption.value 
= txt_value.value;
            
            
// 增加新创建的项到ListBox
            sourceListBox.options[sourceListBox.length] = newOption;
            
            
// 调用我们的ListBox输出到客户端的函数
            AddListItem(sourceListBox,newOption.text, newOption.value);
        }

     }

首先创建一个新项,然后把这个新项插入到ListBox中,之后再把新项增加到用于保存增加项的隐藏字段中。

在回发服务器后,你应该注意到ListBox中的各个项与发送服务端之前的各个项是相同的。这就证明这个控件已经达到了我们预期的功能。


下载
[原文源码下载]
[译者改后源码下载]


结论
在这篇文章里,我们一起知道了如何创建一个基于asp.net里的ListBox控件的新的自定义控件。

另外,我们一起了解了如何解决ListBox和所用继承自ListControl基类的控件的客户端操作无法在回传服务端后保存的问题。

希望你喜欢这篇文章

祝.net开发愉快。
ASP.NET前后端用户安全管理技术全解析 本文系统介绍ASP.NET Core中用户管理的核心技术,涵盖注册登录、密码加密(PBKDF2)、JWT身份认证及AccessToken/RefreshToken机制。通过轻量级Web API项目演示,强调安全实践:密码明文不存储,使用加盐哈希;登录后生成带有效期的JWT令牌,结合短时效AccessToken与安全存储的RefreshToken实现无状态身份验证,提升系统安全性与用户体验。 阅读详情

相关推荐

Coze平台智能体开发实战:打造测试工程师的AI助手

智能体是具备特定身份和能力的AI实体,由大语言模型(LLM)驱动,并通过插件、知识库和工作流扩展其能力。明确的角色定位:可以设定特定身份和专业领域扩展能力:通过插件连接外部工具和服务记忆能力:通过知识库存储和检索专属信息流程化处理:通过工作流执行复杂多步任务通过Coze平台创建测试工程师智能体,可以显著提升测试效率和质量。明确的角色定位:聚焦测试工程师的实际需求丰富的知识库:提供准确的领域知识支持合适的工具集成:通过插件连接现有工具链持续迭代优化:根据反馈不断改进智能体行为自动化测试生成。

hogwarts_beibei的博客 1005

ASP.NET中 ListBox(列表框)的使用

ylbtech-ASP.NET-Control-Basic:ListBox(列表框)的使用 ASP.NET中 ListBox(列表框)的使用。 1.A,运行效果返回顶部 ListBox(列表框) 属性 值 作用 SelectionMode Single|Multiple 列表选择模式:单选|多选 ...

weixin_30731305的博客 250

本地大模型部署实战:LM Studio与Ollama的易用性与性能深度评测

本文对两款主流本地大模型部署工具LM Studio和Ollama进行了深度评测。LM Studio凭借图形化界面和内置模型库,为新手提供了开箱即用的便捷体验,并支持OpenAI兼容API,易于生态集成。Ollama则以命令行驱动,轻量高效,凭借其原生API和Modelfile自定义能力,在自动化集成和性能方面表现突出。文章从易用性、模型生态、性能及扩展性多维度对比,帮助用户根据自身技术背景和使用场景做出最佳选择。

weixin_29039773的博客 528

[翻译]ASP.NET 2.0中的健康监测系统(Health Monitoring)(2) - 通过Email发送监测信息

原文地址:http://aspnet.4guysfromrolla.com/articles/032107-1.aspx[原文源码下载][译者改后源码下载][翻译]ASP.NET 2.0中的健康监测系统(Health Monitoring)(2) - 通过Email发送监测信息原文发布日期:2007.03.21作者:Scott Mitchell翻译:webabcd介绍ASP.NET 2.0

webabcd的专栏 1423

手把手教你用gmid方法设计二级运放:从理论到仿真全流程(附避坑指南)

本文详细介绍了使用gmid方法设计二级运放的全流程,从理论到仿真实践,特别针对初学者常见问题提供避坑指南。通过系统化的晶体管尺寸确定技术,帮助工程师在性能、功耗和面积之间找到最佳平衡点,适用于模拟集成电路设计中的关键模块开发。

weixin_29213525的博客 271

2023年5月青少年软件编程Python等级考试四级真题(含答案和解析)

电子学会,2023年5月,青少年软件编程,Python等级考试,四级真题(含答案和解析)

m0_37554648的博客 903

[翻译]ASP.NET 2.0中的健康监测系统(Health Monitoring)(1) - 基本应用

原文地址:http://aspnet.4guysfromrolla.com/articles/031407-1.aspx[原文源码下载][译者改后源码下载][翻译]ASP.NET 2.0中的健康监测系统(Health Monitoring)(1) - 基本应用原文发布日期:2007.03.14作者:Scott Mitchell翻译:webabcd介绍在程序部署之前,要经历许多软件工程中定义

webabcd的专栏 1157

〔重庆理工大学〕计算机网络实验指导书【实验九 直连路由,静态路由,默认路由配置】

本实验指导书介绍了直连路由、静态路由和默认路由的配置方法。主要内容包括:1)路由器基础知识,包括直连路由、静态路由和动态路由三种路由生成方式;2)路由度量值与匹配顺序,解释了不同路由类型的优先级;3)实验任务分为三个部分:直连路由的查看分析、静态路由的配置以及默认路由的配置,详细说明了配置步骤和命令。实验要求通过模拟器搭建网络环境,完成路由配置使PC间能够互通。实验旨在帮助学生掌握不同路由类型的工作原理和配置方法,适用于简单的网络环境。

Pretty Boy Fox的博客 1054

[翻译]开发自己的web站点管理工具(Website Administration Tool)(2)

原文地址:http://aspnet.4guysfromrolla.com/articles/053007-1.aspx [原文源码下载][翻译]开发自己的web站点管理工具(Website Administration Tool)(2)原文发布日期:2007.05.30作者:Dan Clem翻译:webabcd介绍为了方便管理用户、角色和权限设置,ASP.NET 2.0内置了Web Si

webabcd的专栏 945

pip install mysql出现error: subprocess - exited-with-error的解决方案

本文主要介绍了pip install mysql出现error: subprocess - exited-with-error的解决方案,希望能对使用mysql的同学们有所帮助。 文章目录 1. 问题描述 2. 解决方案

weixin_43178406的博客 5万+

【25届数字IC秋招总结】面试经验13——豪威科技面试

25届数字ic面试记录———豪威科技

lalala0635的博客 362

[翻译]开发一个自己的HTML在线编辑器(一)

原文地址:http://aspalliance.com/1092_Rich_Text_Editor_Part_I[原文源码下载]开发一个自己的HTML在线编辑器(一)摘要在本文中,Haissam Abdul Malak将给大家详细介绍如何使用javascript开发一个HTML在线编辑器,它可以应用于web应用程序中,特别是论坛,社区和博客。这个编辑器支持基于XHTML创建文本的功能。原文

webabcd的专栏 904

【2026年阿里巴巴集团暑期实习- 4月25日-算法岗-第二题- 矩阵计数】(题目+思路+Java&C++&Python解析+在线测试)

摘要: 给定两个非负整数序列a和b,构造n×m矩阵C,其中C[i][j]=a[i]×b[j]。统计矩阵中元素≥k的数量。解法是先对数组b排序,然后对于每个a[i],若k=0则直接累加m;若a[i]=0且k>0则跳过;否则计算需要的最小b[j]值,在排序后的b中使用二分查找确定满足条件的元素数量。时间复杂度为O((n+m)log m),空间复杂度O(1)。代码实现了排序和二分查找的高效组合。

m0_73659489的博客 64

[翻译]开发自己的web站点管理工具(Website Administration Tool)(1)

原文地址:http://aspnet.4guysfromrolla.com/articles/052307-1.aspx [原文源码下载][翻译]开发自己的web站点管理工具(Website Administration Tool)(1)原文发布日期:2007.05.23作者:Dan Clem翻译:webabcd介绍基于Forms的验证,再结合ASP.NET 2.0的成员资格和角色管理系统

webabcd的专栏 855

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

[翻译]ASP.NET 3.5中的ListView控件和DataPager控件

原文地址:http://www.west-wind.com/WebLog/posts/127340.aspx[译者改后源码下载][翻译]ASP.NET 3.5中的ListView控件和DataPager控件原文发布日期:2007.08.02作者:Rick Strahl翻译:webabcd介绍今天,我花了几个小时的时间研究了一下ASP.NET 3.5中的ListView控件和DataPage

webabcd的专栏 816

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

[翻译]开发一个自己的HTML在线编辑器(二)

原文地址:http://aspalliance.com/1156_Rich_Text_Editor__Part_II[原文源码下载][翻译]开发一个自己的HTML在线编辑器(二)原文发布日期:2007.02.27作者:Haissam Abdul Malak翻译:webabcd文章内容介绍javascrit文件后置代码结论介绍在我们一起研究了如何开发一个HTML在线编辑器后(第一部分在这里

webabcd的专栏 788

[翻译]ASP.NET AJAX之内部揭秘

原文地址:http://www.codeproject.com/KB/ajax/aspnetajaxtips.aspx[原文源码下载][翻译]ASP.NET AJAX之内部揭秘原文发布日期:2006.12.22作者:About Omar Al Zabir翻译:webabcd审校:Tony Qu 介绍微软最近发布了ASP.NET AJAX的Be

webabcd的专栏 754

[翻译]在GridView中针对鼠标单击的某一独立单元格进行编辑

原文地址:http://www.codeproject.com/KB/webforms/EditGridviewCells.aspx[原文源码下载][译者改后源码下载][翻译]在GridView中针对鼠标单击的某一独立单元格进行编辑原文发布日期:2007.04.07作者:Declan Bright翻译:webabcd介绍ASP.NET的Gri

webabcd的专栏 746

[翻译]ASP.NET 2.0中的健康监测系统(Health Monitoring)(3) - 触发自定义事件

原文地址:http://aspnet.4guysfromrolla.com/articles/062707-1.aspx[原文源码下载][译者改后源码下载][翻译]ASP.NET 2.0中的健康监测系统(Health Monitoring)(3) - 触发自定义事件原文发布日期:2007.06.27作者:Scott Mitchell翻译:webabcd介绍在之前的文章中(译者注:ASP.N

webabcd的专栏 724

[翻译]ASP.NET AJAX调用Web Service

原文地址:http://www.developer.com/net/asp/article.php/3657826[原文源码下载]ASP.NET AJAX调用Web Service原文发布日期:2007.02.08作者:Bipin Joshi翻译:webabcd介绍尽管AJAX是种客户端技术,但实际上的开发过程,它经常要调用一个服务器端的过程。通常,网站上的数据是存放在一个关系型数据库中,

webabcd的专栏 713

[翻译]使用ASP.NET 2.0中的ReportViewer控件

原文地址:http://www.dotnetbips.com/articles/51df0f69-ee0e-4982-a7bb-d3e9b2182841.aspx[原文源码下载][译者改后代码下载][翻译]使用ASP.NET 2.0中的ReportViewer控件原文发布日期:2007.03.22作者:Bipin Joshi翻译:webabcd介

webabcd的专栏 701

[翻译]代码片断:如何用二进制格式读写图片到数据库

原文地址:http://aspalliance.com/1083_CodeSnip_How_to_ReadWrite_an_Image_to_Database_in_Binary_Format[原文源码下载][译者改后源码下载][翻译]代码片断:如何用二进制格式读写图片到数据库原文发布日期:2006.12.7作者:Sandeep Acharya翻译:webabcd摘要从这段代码中我们将知道

webabcd的专栏 661

[翻译]使用C#创建SQL Server的存储过程(Visual Studio 2005 + SQL Server 2005)

原文地址:http://www.dotnetbips.com/articles/70eff218-3da0-4f6f-8f8d-eeea65193f2c.aspx[原文源码下载][翻译]使用C#创建SQL Server的存储过程(Visual Studio 2005 + SQL Server 2005)原文发布日期:2007.06.17作者:Bipin Joshi翻译:webabcd介绍通

webabcd的专栏 573

V8 机制、手写核心函数与 TypeScript 类型体操

或固定初始化(如数组先定长、对象先给全字段)保持类型与形状稳定;这些都比"换框架"更基础。只能处理纯数据(丢函数、Date、RegExp、循环引用报错)。生产级深拷贝要处理:原始值短路、循环引用、V8(Chrome / Node 的 JS 引擎)不是"解释一行跑一行"那么简单,它用。图:V8 执行流程——解释执行 + 热点优化,优化失败会 Deopt 回退。JS 内存自动管理,但"自动"不等于"不会漏"。是"固定间隔最多执行一次"。手写 Promise 是"懂异步"的试金石。是"停下后才执行最后一次",

qq_38468358的博客 327
上一篇: [翻译]代码片断:如何用二进制格式读写图片到数据库
下一篇: [翻译]动态创建GridView的列(第一部分)
webabcd
博客等级 码龄17年 28粉丝 911原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值