两个字符串的特殊连接的更好方法

时间:2013-07-24 16:48:53

标签: c# javascript asp.net string

我希望以这种方式连接两个字符串,即在第一个字符串的第一个字符之后,第二个字符串的第一个字符到来,然后是第一个字符串的第二个字符,然后是第二个字符串的第二个字符来等等。最好的解释一些例子:

    s1="Mark";
    s2="Zukerberg";  //Output=> MZaurkkerberg

如果:

    s1="Zukerberg";
    s2="Mark"        //Output=> ZMuakrekrberg

如果:

    s1="Zukerberg";
    s2="Zukerberg";  //Output=> ZZuukkeerrbbeerrgg

我编写了以下代码,它给出了预期的输出,但它似乎是很多代码。有没有更有效的方法来做到这一点?

public void SpecialConcat(string s1, string s2)
        {
            string[] concatArray = new string[s1.Length + s2.Length];
            int k = 0;
            string final = string.Empty;
            string superFinal = string.Empty;
            for (int i = 0; i < s1.Length; i++)
            {
                for (int j = 0; j < s2.Length; j++)
                {
                    if (i == j)
                    {
                        concatArray[k] = s1[i].ToString() + s2[j].ToString();
                        final = string.Join("", concatArray);
                    }
                }
                k++;
            }
            if (s1.Length > s2.Length)
            {
                string subOne = s1.Remove(0, s2.Length);
                superFinal = final + subOne;
            }
            else if (s2.Length > s1.Length)
            {
                string subTwo = s2.Remove(0, s1.Length);
                superFinal = final + subTwo;
            }
            else
            {
                superFinal = final;
            }
            Response.Write(superFinal);
        }
    }

我也在Javascript中编写了相同的逻辑,但工作正常但很多代码。

10 个答案:

答案 0 :(得分:7)

var s1 = "Mark";
var s2 = "Zukerberg";
var common = string.Concat(s1.Zip(s2, (a, b) => new[]{a, b}).SelectMany(c => c));
var shortestLength = Math.Min(s1.Length, s2.Length);
var result = 
     common + s1.Substring(shortestLength) + s2.Substring(shortestLength);

答案 1 :(得分:5)

在JavaScript中,使用字符串时,您也在使用数组,因此它会更容易。此外+将为您连接。如果您想要IE7支持,请用charAt替换字符串索引。

这是小提琴:

http://jsfiddle.net/z6XLh/1

var s1 = "Mark";
var s2 = "ZuckerFace";
var out ='';

var l = s1.length > s2.length ? s1.length : s2.length
for(var i = 0; i < l; i++) {
    if(s1[i]) {
        out += s1[i];
    }
    if(s2[i]){
        out += s2[i];
    }
}
console.log(out);

答案 2 :(得分:5)

var stringBuilder = new StringBuilder();
for (int i = 0; i < Math.Max(s1.Length, s2.Length); i++)
{
    if (i < s1.Length)
        stringBuilder.Append(s1[i]);

    if (i < s2.Length)
        stringBuilder.Append(s2[i]);
}

string result = stringBuilder.ToString();

答案 3 :(得分:3)

static string Join(string a, string b)
{
   string returnVal = "";
   int length = Math.Min(a.Length, b.Length);
   for (int i = 0; i < length; i++)
      returnVal += "" + a[i] + b[i];

   if (a.Length > length)
      returnVal += a.Substring(length);
   else if(b.Length > length)
      returnVal += b.Substring(length);

   return returnVal;
}

可以通过stringbuilder进行改进

答案 4 :(得分:3)

只是为了好奇,这里有一个难以理解的单行(我已经拆分了多行;)

这使用了这样的事实:如果字符串已经至少为该长度,则将字符串填充到特定长度不起作用。这意味着将每个字符串填充到另一个字符串的长度将导致使用空格填充,较短的字符串与较长字符串的长度填充。

然后我们使用.Zip()将每对字符串联成一个字符串。

然后我们调用string.Concat(IEnumerable<string>)将压缩字符串连接成一个字符串。

最后,我们使用string.Replace()删除我们之前介绍的额外填充空间。

var result = string.Concat
(
    s1.PadRight(s2.Length)
    .Zip
    (
        s2.PadRight(s1.Length), 
        (a,b)=>string.Concat(a,b)
    )
).Replace(" ", null);

在一行[在此处插入编码恐怖图标]:

var result = string.Concat(s1.PadRight(s2.Length).Zip(s2.PadRight(s1.Length), (a,b)=>string.Concat(a,b))).Replace(" ", null);

答案 5 :(得分:2)

就在我的头顶,我就是这样做的。

        var s1Length = s1.Length;
        var s2Length = s2.Length;
        var count = 0;
        var o = "";
        while (s1Length + s2Length > 0) {
            if (s1Length > 0) {
                s1Length--;
                o += s1[count];
            }
            if (s2Length > 0) {
                s2Length--;
                o += s2[count];
            }
            count++;
        }

答案 6 :(得分:2)

这是另一个单行:

var s1 = "Mark";
var s2 = "Zukerberg";
var result = string.Join("", 
  Enumerable.Range(0, s1.Length).ToDictionary(x => x * 2, x => s1[x])
  .Concat(Enumerable.Range(0, s2.Length).ToDictionary(x => x * 2+1, x => s2[x]))
  .OrderBy(d => d.Key).Select(d => d.Value));

基本上,这会将两个字符串转换为带有键的字典,这些键将使得到的字符串能够正确排序。 Enumerable范围用于将索引与字符串中的每个字母相关联。当我们存储字典时,它将s1上的索引乘以2,得到&lt; 0,M&gt;,&lt; 2,a&gt;,&lt; 4,r&gt;,&lt; 6,k&gt;,并将s2乘以2然后加1,得到&lt; 1,Z&gt;,&lt; 3,u&gt;,&lt; 5,k&gt;等。

一旦我们有了这些词典,我们就将它们与.Concat结合起来,然后用.OrderBy对它们进行排序,它给我们&lt; 0,M&gt;,&lt; 1,Z&gt;,&lt; 2,a&gt;,&lt; 3,u&gt;,...然后我们将它们转换为最后一个字符串,并在开头使用string.join。

答案 7 :(得分:1)

好的,这是我能提出的第二个最短的解决方案:

    public string zip(string s1, string s2)
    {
        return (string.IsNullOrWhiteSpace(s1+s2))
            ? (s1[0] + "" + s2[0] + zip(s1.Substring(1) + " ", s2.Substring(1) + " ")).Replace(" ", null)
            : "";
    }

    var result =  zip("mark","zukerberg");

糟糕!我最初的最短时间与上面的标记相同...所以,第二个最短的我可以拿出来!我希望我能用递归来减少它,但不是那么多。

答案 8 :(得分:1)

var sWordOne = "mark";// ABCDEF
var sWordTwo = "zukerberg";// 123
var result  = (sWordOne.Length > sWordTwo.Length) ? zip(sWordOne, sWordTwo) : zip(sWordTwo, sWordOne);
//result = "zmuakrekrberg"


 static string zip(string sBiggerWord, string sSmallerWord)
{
    if (sBiggerWord.Length < sSmallerWord.Length) return string.Empty;// Invalid 
    if (sSmallerWord.Length == 0) sSmallerWord = " ";
    return string.IsNullOrEmpty(sBiggerWord) ? string.Empty : (sBiggerWord[0] + "" + sSmallerWord[0] + zip(sBiggerWord.Substring(1),sSmallerWord.Substring(1))).Replace(" ","");
}

答案 9 :(得分:0)

没有Linq巫术的简单选择:

def chosen():
    if 815 + 70 > mouse[0] > 815 and 115 + 70 > mouse[1] > 110:
        pygame.draw.rect(view, gray,(815,115,70,70))
        if pygame.mouse.get_pressed() == (1,0,0) and 815 + 70 > mouse[0] > 815 and 115 + 70 > mouse[1] > 115:
                return "redcav1"
                pygame.draw.rect(view, gray,(815,115,70,70))
        elif 815 + 70 > mouse[0] > 815 and 215 + 70 > mouse[1] > 215:
            pygame.draw.rect(view, gray,(815,215,70,70))
            if pygame.mouse.get_pressed() == (1,0,0) and 815 + 70 > mouse[0] > 815 and 215 + 70 > mouse[1] > 215: 
                return "redcav2"

if chosen() == "redcav1":
    pygame.draw.rect(view, gray,(815,115,70,70))
elif chosen() == "redcav2":
    pygame.draw.rect(view, gray, (815,215,70,70))
else:
    chosen()
print chosen()