4

I want to concatenate two strings in such a way, that after the first character of the first string, the first character of second string comes, and then the second character of first string comes and then the second character of the second string comes and so on. Best explained by some example cases:

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

if:

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

if:

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

I've written the following code which gives the expected output but its seems to be a lot of code. Is there any more efficient way for doing this?

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);
        }
    }

I have written the same logic in Javascript also, which works fine but again a lot of code.

4

10 回答 10

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);
于 2013-07-24T16:59:39.343 回答
5

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

这是小提琴:

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);
于 2013-07-24T16:54:17.573 回答
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();
于 2013-07-24T17:04:51.330 回答
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);
于 2013-07-24T18:29:18.333 回答
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 改进

于 2013-07-24T17:00:58.447 回答
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++;
        }
于 2013-07-24T17:14:42.160 回答
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));

基本上,这会将两个字符串都转换为带有键的字典,这些键将使结果字符串正确排序。可枚举范围用于将索引与字符串中的每个字母相关联。当我们存储字典时,它将s1上的索引乘以2,得到<0,M>,<2,a>,<4,r>,<6,k>,然后将s2乘以2然后加1,导致 <1,Z>,<3,u>,<5,k> 等。

一旦我们有了这些字典,我们将它们与 .Concat 组合并使用 .OrderBy 对它们进行排序,这给了我们 <0,M>,<1,Z>,<2,a>,<3,u>,.. . 然后我们只是将它们转储到最后的字符串中,以 string.join 开头。

于 2013-07-24T20:10:00.680 回答
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");

哎呀!我最初的最短与上面的标记相同......所以,我能想到的第二个最短!我曾希望我可以通过递归真正削减它,但不是那么多。

于 2013-07-24T21:15:43.237 回答
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(" ","");
}
于 2018-06-10T18:08:52.693 回答
0

没有 Linq 巫术的简单替代方案:

string Merge(string one, string two)
{
    var buffer = new char[one.Length + two.Length];
    var length = Math.Max(one.Length, two.Length);
    var index = 0;

    for (var i = 0; i < length; i ++)
    {
        if (i < one.Length) buffer[index++] = one[i];
        if (i < two.Length) buffer[index++] = two[i];
    }

    return new string(buffer);
}
于 2019-01-21T02:13:14.783 回答