我有一个令牌类的后续字符列表:
3 ( 16 ) 23 ( 24 ( 40 ) 50 ( 66 ) 76 ) 83 ( 88 ( 104 ) 127 )
我的要求是在此列表中找到一对括号。在列表中,括号对是:3,16; 24,40; 50,66; 23,76; 88104; 83127
我正在尝试使用以下方法:
public static Dictionary<int,int> GetPair(List<Token> data)
{
List<Token> token = data;
var pair = new Dictionary<int, int>();
int startIndex = -1;
int currentPosition = -1;
int finalIndex = -1;
foreach (var item in token)
{
if (item.TokenValue == "(" && (currentPosition == -1 || currentPosition>startIndex) )
{
startIndex = item.TokenID;
currentPosition = startIndex;
}
if (item.TokenValue == ")")
{
finalIndex = item.TokenID;
currentPosition = finalIndex;
pair.Add(startIndex, finalIndex);
}
}
return pair;
}
public class Token
{
public int TokenID { get; set; }
public string TokenValue { get; set; }
}
我一直在寻找“23”的位置,因为列表中还有另一个左括号,它用“24(”代替它。请帮助我修改逻辑吗?
答案 0 :(得分:3)
我没有测试过,但这应该可以解决问题:
public static Dictionary<int,int> GetPair(List<Token> data)
{
var pair = new Dictionary<int, int>();
var stack = new Stack<Token>();
foreach (var item in token)
{
if (item.TokenValue == "(")
{
stack.Push(item);
continue;
}
if (item.TokenValue == ")")
{
var starting = stack.Pop();
pair.Add(starting.TokenId, item.TokenId);
}
}
return pair;
}
答案 1 :(得分:1)
这是一个经典的访谈qustion,你用Stack
解决它:
public static Dictionary<int,int> GetPair(List<Token> data)
{
Stack<Token> stacken = new Stack<Token>();
var pair = new Dictionary<int, int>();
Token temp = new Token();
foreach (char A in data)
{
if (item.TokenValue == "(" )
{
stacken.Push(A);
}
if (item.TokenValue == ")" )
{
if (stacken.Last() == '(')
{
temp = stacken.Pop();
pair.Add(temp.TokenID,item.TokenID)
}
else
{
stacken.Push(A);
}
}
}
return pair;
}
答案 2 :(得分:0)
您也可以使用正则表达式。可能它不像Vera rind解决方案那么快。
var i=$('table tr').length;
$(".addmore").on('click',function(){
count=$('table tr').length;
var data="<tr><td><input type='checkbox' class='case'/></td><td><span id='snum"+i+"'>"+count+".</span></td>";
data +="<td><input class='form-control' type='text' id='countryname_"+i+"' name='countryname[]'/></td> <td><input class='form-control' type='text' id='country_no_"+i+"' name='country_no[]'/></td><td><input class='form-control' type='text' id='phone_code_"+i+"' name='phone_code[]'/></td><td><input class='form-control' type='text' id='country_code_"+i+"' name='country_code[]'/></td></tr>";
$('table').append(data);
row = i ;
$('#countryname_'+i).autocomplete({
source: function( request, response ) {
$.ajax({
url : "<?php echo base_url(); ?>admin/billing/get_country",
dataType: "json",
method: 'post',
data: {
name_startsWith: request.term,
type: 'country_table',
row_num : row
},
success: function( data ) {
response( $.map( data, function( item ) {
var code = item.split("|");
return {
label: code[0],
value: code[0],
data : item
}
}));
}
});
},
autoFocus: true,
minLength: 0,
select: function( event, ui ) {
var names = ui.item.data.split("|");
id_arr = $(this).attr('id');
id = id_arr.split("_");
$('#country_no_'+id[1]).val(names[1]);
$('#phone_code_'+id[1]).val(names[2]);
$('#country_code_'+id[1]).val(names[3]);
}
});
答案 3 :(得分:0)
修改强>
感谢 Vera rind 建议,我还写了解决方案,为每个(嵌套级别)使用.NET正则表达式,使用正则表达式:
(?<first>\d+)(?=\s\(\s(?<second>\d+)\s\))|(?<first>\d+)\s(?=\(\s(?:(?:[^()]|(?<Open>\()|(?<Content-Open>\)))+(?(Open)(?!))\s(?<second>\d+)))
它会捕获组first
和second
中的值对。正则表达式直接匹配对的第一个值,第二个值由正向前瞻的组捕获。它不是最有效的方法,只要正确匹配就更容易在正则表达式测试器中验证。
OLD ANSWER
在其他正则表达式中(据我所知),没有这种优雅的方式来匹配平衡的可重复结构,因此对于两级括号,此解决方案仍然有效。在这种情况下,确切的解决方案更好,但如果整个数据的格式相同(间距和最大两个级别的paratheses深度),也可以使用正则表达式:
(\d+)\s\(\s(\d+)\s\)|(\d+)(?=\s\(\s(?:\d+\s\(\s\d+\s\)\s)+(\d+))
其中:
(\d+)\s\(\s(\d+)\s\)
- 匹配简单案例:namber与以下内容
括号中的数字:n1 (n2)
,值在第1组和第1组中捕获2,(\d+)(?=\s\(\s(?:\d+\s\(\s\d+\s\)\s)+(\d+))
- 匹配号码
以下嵌套括号中的最后一个孤独数字:n1 ( x1 (x2) y1 (y2) n2 )
,值在第3组和第3组中捕获4,然而它会变化列表顺序。