public static Elem <AddrPort> InsertNext(Elem <AddrPort> elem, AddrPort newAddrPort) { return(InsertNext(elem, new Elem <AddrPort>(newAddrPort))); }
/// <summary> /// aはlowerよりもlowerか /// </summary> /// <param name="a"></param> /// <param name="lower"></param> /// <returns></returns> public bool IsLower(Elem <AddrPort> a, Elem <AddrPort> lower) { throw new NotImplementedException(); }
/// <summary> /// /// </summary> /// <param name="part1"></param> /// <param name="part2"></param> /// <returns>できたやつと結合できなかったやーつ</returns> public static CircleAndNotResolved <IEnumerable <AddrPort> > Concat(Elem <AddrPort> circle, IEnumerable <AddrPort> part2) { //空 if (circle.Count == 1 && circle.IsEmpty) { foreach (var addrPort in part2) { circle = InsertNext(circle, addrPort); } return(new CircleAndNotResolved <IEnumerable <AddrPort> >(circle, new List <AddrPort>())); } var part = part2.ToList(); for (int i = 0; i < part.Count; i++) { var start = circle; var current = circle; do { if (!current.IsEmpty && current.Value.Equals(part[i])) { if (i == 0) { //もし、次の空で無い要素が2つ目以降と一致したら、一致したところまでをつなぎ替える var t = current;//次の空でない要素 do { t = t.After; } while (t.IsEmpty); for (int m = 1; m < part.Count; m++) { if (t.Value.Equals(part[m])) { Replace(current, t.After, part.GetRange(i + 1, m)); // System.Diagnostics.Debug.WriteLine(circle.ToStr()); //一致したところ以降は最初から return(Concat(circle, part.GetRange(m, part.Count - m))); } } //次の要素も一致したら最初の要素を削除してもう一回最初から。 if (i + 1 < part.Count && !current.After.IsEmpty && current.After.Value.Equals(part[i + 1])) { part.RemoveAt(i); return(Concat(circle, part)); } //3要素目以降でもし一致したら一致したところまでを新しい要素に付け替える。これで途中にEmptyがあっても消える Elem <AddrPort> matchElem = null; int j;//一致したインデックス for (j = 2; j < part.Count; j++) { matchElem = GetElement(circle, part[j]); } if (matchElem == null) { //既に登録済みの中に今回の分の2つ目以降の要素は含まれていなかった。今回の分が1つしか無かった場合もここに来る。余分な計算をする羽目になるが、一般的に考える。 if (i + 1 < part.Count) { //2つ目以降の要素を挿入する。 InsertNext(current, part.GetRange(i + 1, part.Count - (i + 1))); } return(new CircleAndNotResolved <IEnumerable <AddrPort> >(circle, new List <AddrPort>())); } Replace(current, matchElem.After, part.GetRange(i + 1, part.Count - (i + j))); if (j + 1 < part.Count) { //一致した以降にまだ要素があったら、一致した要素以降をもう一回最初から part.RemoveRange(0, j - 1); return(Concat(circle, part)); } } else { //2つ目以降が一致した。 //一致したところまでの要素を単純につなぎ、再度やり直す。 InsertNext(current.Before, part.GetRange(0, i)); part.RemoveRange(0, i); return(Concat(circle, part)); } } current = current.After; } while (current != start); } //一切一致しなかった。 return(new CircleAndNotResolved <IEnumerable <AddrPort> >(circle, part2)); }
/// <summary> /// /// </summary> /// <param name="circle"></param> /// <param name="parts"></param> /// <returns></returns> public static CircleAndNotResolved <IEnumerable <IEnumerable <AddrPort> > > Concat(Elem <AddrPort> circle, IEnumerable <IEnumerable <AddrPort> > parts) { var ret0 = circle; var list = parts.ToList(); int before; int after; //listの要素数が変わらなくなるまでひたすら繰り返す。 do { var tmp = new List <IEnumerable <AddrPort> >(); before = list.Count(); for (int i = 0; i < list.Count; i++) { var arr = list[i]; var ret = ProviderAddrPortResolver.Concat(ret0, arr); if (ret.NotResolved.Count() != 0) { tmp.Add(ret.NotResolved); } ret0 = ret.Circle; } list = tmp; after = list.Count(); } while (before != after); return(new CircleAndNotResolved <IEnumerable <IEnumerable <AddrPort> > >(ret0, list)); }
public CircleAndNotResolved(Elem <AddrPort> circle, T notResolved) { Circle = circle; NotResolved = notResolved; }
public ProviderAddrPortResolver() { AddrPortCircle = CreateEmptyCircle(); }