ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 Excel Home精品图文教程库
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
300集Office 2010微视频教程 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
楼主: lee1892

[Excel 程序开发] [第99期][VBA&函数公式]最少的旋转次数[已总结]

  [复制链接]

TA的精华主题

TA的得分主题

发表于 2013-10-30 14:44 | 显示全部楼层
本帖最后由 CheryBTL 于 2013-10-31 21:17 编辑

函数公式(刚好120字符):
  1. =MATCH(,MMULT(N(MID(A2,ROW($2:100),99)&LEFT(A2,ROW($1:99))>MID(A2,COLUMN(B:CV),99)&LEFT(A2,COLUMN(A:CU))),ROW(1:99)^0),)
复制代码
取巧(117字符):
  1. =MATCH(,MMULT(N(MID(A2,ROW($2:100),99)&LEFT(A2,ROW($1:99))>MID(A2,COLUMN(B:CV),99)&LEFT(A2,COLUMN(A:CU))),Z1:Z99+1),)
复制代码
按字符串长度小于100(即最大为99时),再省一个字符:
  1. =MATCH(,MMULT(N(MID(A2,ROW($2:99),99)&LEFT(A2,ROW($1:98))>MID(A2,COLUMN(B:CU),99)&LEFT(A2,COLUMN(A:CT))),Z1:Z98+1),)
复制代码


献丑了,第一次用VBA答题,原来代码太罗嗦了,简化下:(怪了,为什么显示的是两遍代码?):
  1. Function MinRot(ByVal sStr As String) As Long
  2.     Dim t#
  3.     t = Timer
  4.     Dim i As Long, tempnum As Long, sLen As Long
  5.     Dim tempstr() As String
  6.     Dim str_start As String, strF As String, strtemp As String
  7.     '//str_start为26个字符中出现的最小字符
  8.     '//strF 为最小的字符串,strtemp 为过程所得到的字符串
  9.     strF = sStr: MinRot = 0
  10.     sLen = Len(sStr)
  11.     For i = 97 To 122
  12.         str_start = Chr(i)
  13.         If InStr(sStr, str_start) > 0 Then
  14.             tempstr = Split(sStr, str_start)
  15.             Exit For
  16.         End If
  17.     Next i
  18.     For i = 0 To UBound(tempstr)
  19.         tempnum = tempnum + Len(tempstr(i)) + 1
  20.         strtemp = Mid(sStr, tempnum, sLen) & Left(sStr, tempnum - 1)
  21.         If strtemp < strF Then strF = strtemp: MinRot = tempnum - 1
  22.     Next i
  23.     t = Timer - t
  24.     Debug.Print "ID: " & "<CheryBTL>"
  25.     Debug.Print "Answer is: " & MinRot
  26.     Debug.Print "Time used: " & Format(t, "0.000s")
  27. End Function
复制代码

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2013-10-31 10:20 | 显示全部楼层
题一VBA解答:
  1. Function minrot(ByVal sstr As String) As Long
  2.     Dim t#
  3.     t = Timer
  4.     '……
  5.     '-----huahua2005编写分割线-----
  6.    
  7.     sstr = sstr & sstr & ".000001"
  8.     For minrot = 1 To (InStr(1, sstr, ".") - 1) / 2 Step 1
  9.         If Mid(sstr, (InStr(1, sstr, ".") - 1) / 2 + 1, (InStr(1, sstr, ".") - 1) / 2) > _
  10.            (Mid(sstr, minrot, (InStr(1, sstr, ".") - 1) / 2 - minrot + 1) & Mid(sstr, 1, minrot - 1)) Then
  11.            
  12.             sstr = Left(sstr, (InStr(1, sstr, ".") - 1) / 2) & Mid(sstr, minrot, (InStr(1, sstr, ".") - 1) / 2 - minrot + 1) _
  13.                  & Mid(sstr, 1, minrot - 1) & minrot * 0.000001
  14.         End If
  15.     Next minrot
  16.     minrot = Right(sstr, Len(sstr) - InStr(1, sstr, ".") + 1) * 10 ^ 6 - 1
  17.    
  18.   '-----huahua2005编写分割线-----
  19.   
  20.     t = Timer - t
  21. Debug.Print "ID: " & "huahua2005"
  22. Debug.Print "Answer is: " & minrot
  23. Debug.Print "Time used: " & Format(t, "0.000s")
  24. End Function
复制代码
题二:函数思考中......

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2013-10-31 11:46 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
不知道合符题意不 但是没有测试10W字符串
  1. Public Function MinRot(ByVal sStr As String) As Long
  2.     Dim t#
  3.     t = Timer
  4.     Dim L As Long, minv As Long
  5.     MinRot = 0
  6.     L = Len(sStr)
  7.     Nstr = sStr + sStr
  8.     Dim Arr() As String
  9.     ReDim Arr(0 To L - 1)
  10.     For i = 0 To L - 1
  11.         Arr(i) = Mid(Nstr, i + 1, L)
  12.         If Arr(i) < Arr(MinRot) Then
  13.             MinRot = i
  14.         End If
  15.     Next
  16.     t = Timer - t
  17.     Debug.Print "ID: " & "<doryan>"
  18.     Debug.Print "Answer is: " & MinRot
  19.     Debug.Print "Time used: " & Format(t, "0.000s")
  20. End Function
复制代码

评分

1

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2013-10-31 11:51 | 显示全部楼层
本帖最后由 lee1892 于 2013-10-31 12:03 编辑

参考解题:

首先考察最小字典顺序的查找逻辑:
1、比较前后两个字符(此后称左指针和右指针,左前右后)
初始:yzyx********************
2、左小则右向后移动继续比较(此处左要移到本次对比循环开始的位置)
左小:yzyx********************
3、左右相同则同时向后移继续比较
相同:yzyx********************
4、右小则左向后移动继续比较(新一轮的比较)
右小:yzyx********************
5、退出循环比较的机制则是:左到达末尾或是右转一圈追上左

于是就有下面这样的代码:
[code=vb]Function MinRot_1&(ByRef sStr$)
    Dim nLen&, i&, iLetL%, iLetR%, nLeft&, nRight&, nRes&, bFlag As Boolean
    nLen = Len(sStr)
    For i = 1 To nLen
        nLeft = i: nRight = i + 1: bFlag = False
        Do
            iLetL = Asc(Mid(sStr, nLeft, 1))
            iLetR = Asc(Mid(sStr, (nRight - 1) Mod nLen + 1, 1))
            If iLetL < iLetR Then
                 nRes = i: nLeft = i: nRight = nRight + 1
            ElseIf iLetL = iLetR Then
                nLeft = nLeft + 1: nRight = nRight + 1
            Else
                Exit Do
            End If
            If nLeft = nLen Then Exit Do
            If (nRight - 1) Mod nLen + 1 = nLeft Then bFlag = True: Exit Do
        Loop
        If bFlag Then Exit For
    Next
    MinRot_1 = nRes - 1
End Function[/code]
上面这段代码对付基本随机的字符串是没什么大问题的,但如果字符大量重复,则会退化成 O(N^2) 的时间复杂度。为满足速度要求,势必要设计成 O(N) 的算法。

考察上述代码逻辑,其主要问题出现在左比右大的情况,此时会大步倒退到开始对比处的下一个(即执行Next i)重新开始对比。而实际上当前左指针左侧的字符已经都比较过了,完全可以从当前左指针的下一个开始下一轮对比,所以只需要在Exit Do 之前加一句 i=nLeft 即可大踏步的前进了。再重复一遍改进后的代码:
[code=vb]Function MinRot_2&(ByRef sStr$)
    Dim nLen&, i&, iLetL%, iLetR%, nLeft&, nRight&, nRes&, bFlag As Boolean
    nLen = Len(sStr)
    For i = 1 To nLen
        nLeft = i: nRight = i + 1: bFlag = False
        Do
            iLetL = Asc(Mid(sStr, nLeft, 1))
            iLetR = Asc(Mid(sStr, (nRight - 1) Mod nLen + 1, 1))
            If iLetL < iLetR Then
                 nRes = i: nLeft = i: nRight = nRight + 1
            ElseIf iLetL = iLetR Then
                nLeft = nLeft + 1: nRight = nRight + 1
            Else
                i = nLeft: Exit Do
            End If
            If nLeft = nLen Then Exit Do
            If (nRight - 1) Mod nLen + 1 = nLeft Then bFlag = True: Exit Do
        Loop
        If bFlag Then Exit For
    Next
    MinRot_2 = nRes - 1
End Function[/code]

继续观察上述代码,可以发现外部的For循环其实并未起到什么太大的作用,仅仅是在给左指针赋初值。来作一下手术:
1、由于需要保留左指针的初始位置,不能在循环体内改变其值,引入偏移量变量,左右指针变量变为初始位置,比较的字符为左右指针加偏移量指向的字符。
2、循环的退出机制中,右指针转一圈追上左指针意味着偏移量等于字符串长度。
3、不再需要记录结果位置,因为左指针始终指向找到的最小字典顺序的第一个字符。
于是演变成如下代码:
[code=vb]Function MinRot_3&(ByRef sStr$)
    Dim nLen&, i&, iLetL%, iLetR%, nLeft&, nRight& ', nRes&, bFlag As Boolean
    Dim nOff&
    nLen = Len(sStr)
    'For i = 1 To nLen
        nLeft = 1: nRight = 2 ': bFlag = False
        nOff = 0
        Do
            iLetL = Asc(Mid(sStr, nLeft + nOff, 1))
            iLetR = Asc(Mid(sStr, (nRight + nOff - 1) Mod nLen + 1, 1))
            If iLetL < iLetR Then
                'nRes = i: nLeft = i: nRight = nRight + 1
                nRight = nRight + nOff + 1
                nOff = 0
            ElseIf iLetL = iLetR Then
                'nLeft = nLeft + 1: nRight = nRight + 1
                nOff = nOff + 1
            Else
                'i = nLeft: Exit Do
                nLeft = nLeft + nOff + 1
                nRight = nLeft + 1
                nOff = 0
            End If
            k = k + 1
            If nLeft + nOff = nLen Then Exit Do
            'If (nRight - 1) Mod nLen + 1 = nLeft Then bFlag = True: Exit Do
            If nOff = nLen Then Exit Do
        Loop
        'If bFlag Then Exit For
    'Next
    MinRot_3 = nLeft - 1 ' 左指针指向的即为最小字典顺序的第一个字符
End Function[/code]

如果再仔细考虑一下左大于右的时候,上述代码将左指针移到了当前对比左指针的后面一位,此时如果右指针的初始值在其右侧,那么就还可以向后移动至右指针(自行考虑一下原因)。

至此,算法优化完毕。再加一个加速技巧就是使用Byte数组以直接获得字符串的ASC码的数组,从而避免反复调用Mid函数。最终我准备的参考答案如下:
[code=vb]Function MinRot&(ByRef sStr$)
    Dim t#
    t = Timer
    Dim aStr() As Byte, nLen&, nCurrent&, nOffset&, nLeft%, nRight%
    aStr = sStr
    nLen = Len(sStr)
    MinRot = 0: nCurrent = 1: nOffset = 0
    Do While nOffset < nLen And MinRot + nOffset + 1 < nLen
        nLeft = aStr((MinRot + nOffset) * 2)
        nRight = aStr(((nCurrent + nOffset) Mod nLen) * 2)
        If nLeft = nRight Then
            nOffset = nOffset + 1
        ElseIf nLeft < nRight Then
            nCurrent = nCurrent + nOffset + 1: nOffset = 0
        Else
            MinRot = MinRot + nOffset + 1
            If nCurrent > MinRot Then MinRot = nCurrent
            nCurrent = MinRot + 1: nOffset = 0
        End If
    Loop
    Erase aStr
    t = Timer - t
    Debug.Print "       ID: " & "Lee1892 - Byte Array"
    Debug.Print "Answer is: " & MinRot
    Debug.Print "Time used: " & Format(t, "0.000s")
End Function[/code]

最初准备的关于此题的一些参考:
[code=vb]'| ======================================================= |'
'|  最小旋转次数
'|  By Lee1892 @ 2013.10.11
'| ------------------------------------------------------- |'
'|  算法逻辑:
'|      1、设置左、右两个指针,对应指向字符串左、右两个字
'|         符,供后续比较。初始设置为左指向第一个字符,右
'|         指向第二个字符。
'|      2、设置变量偏移量,初始值为 0,供后续循环使用。
'|      3、对比左指针+偏移量和右指针+偏移量指向的两个字符
'|         分为下述三种情况:
'|      3.1、如果两者相等,则偏移量右移一位,即当前比较的
'|           左右两指针加偏移量都向右移动一位;
'|      3.2、如果左指针+偏移量指向的字符较小,则右指针移动
'|           到当前比较字符右侧后面一位,偏移量设为 0,即
'|           当前比较左侧小,则右侧移到当前比较后一位;
'|      3.3、如果右指针+偏移量指向的字符较小,则左指针移动
'|           到当前比较字符右侧后面一位,偏移量设为0,参考
'|           3.2步的逻辑;此时对于右指针,如果此时左指针在
'|           右指针左侧,则将左指针移到右指针处。最后将右
'|           指针移到左指针后面一位,开始新一轮比较查找;
'|      4、退出循环3的机制:
'|           偏移量达到字符串长度 或
'|           左指针到达字符串末端
'|      5、退出循环后,左指针指向的为最小字符串的第一个字  
'|         符,所以最小转动次数等于左指针-1
'|      参考代码 MinRotMid                                 
'| ------------------------------------------------------- |'
'|  使用的技巧:
'|      1、MOD运算符计算指针超过字符串长度时对应原字符串的
'|         位置,或元素下标于数组中。
'|      1.1、对于以 0 开始计数,元素(或字符)个数为 n 个
'|           第 i 个(i > n)对应为 i MOD n
'|      1.2、对于以 1 开始计数,元素(或字符)个数为 n 个
'|           第 i 个(i > n)对应为 (i - 1) MOD n + 1
'|      2、使用 Byte 数组实现对字符串中字符的逐个操作,相
'|         较于 Mid 函数或语句而言,使用 Byte 数组的速度要
'|         快很多,4~5倍。其机制是直接复制字符串对应的内存
'|         块到数组的对应的内存块中,而后使用数组来循环操
'|         作,避免了大量的 Mid 函数或语句的寻址时间。
'|      2.1、数组取值,可直接采用 arrByte = strString  
'|      2.2、同样的,改变了数组中的值后,可直接将其赋值给
'|           字符串,如 strString = arrByte
'|      2.3、Byte 数组每两个元素由前至后的对应字符串中的一
'|           个字符,两个元素中前者为低位ASC码后者为高位。
'|      2.4、如数组下标由 0 开始,则字符串中第 i 个字符对
'|           应于数组中的第 2 * (i - 1) 和 2 * i - 1 两个
'|           元素。
'|      2.5、对于“a”~“z”的26个字母而言,只需操作两元素中的
'|           前者,后者值为 0。
'| ======================================================= |'[/code]

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2013-11-1 11:47 | 显示全部楼层
本帖最后由 zm0115 于 2013-11-1 15:02 编辑

不懂算法,这样可行?先占个位置!
Function MinRot(ByVal sStr As String) As Long
   Dim T#
    Dim MyStr$
    Dim Ks1$, Kk1%
    Dim Ks2$, Kk2%
    Dim c%, Lc%
    T = Timer
    '......
    Lc = Len(sStr)
    MyStr = sStr & sStr
    Kk1 = 1: Kk2 = Lc
    Do While Kk1 < Kk2
        If Mid(MyStr, Kk1, Lc) > Mid(MyStr, Kk2, Lc) Then
              c = Kk2
              Kk1 = Kk1 + 1
        Else
              c = Kk1
              Kk2 = Kk2 - 1
        End If
    Loop
    MinRot = c - 1
    '......
    T = Timer - T
    Debug.Print "ID: " & "zm0115"
    Debug.Print "Answer is: " & MinRot
    Debug.Print "Time used: " & Format(T, "0.000s")
End Function


评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2013-11-4 13:46 | 显示全部楼层
本帖最后由 delete_007 于 2013-11-21 14:30 编辑

答一个函数的:
第一版,200字符整:
  1. =98-RIGHT(MAX(MMULT(--(MID(A2&A2,ROW(INDIRECT("1:"&LEN(A2))),LEN(A2))<=MID(A2&A2,TRANSPOSE(ROW(INDIRECT("2:"&LEN(A2)+1))),LEN(A2))),ROW(INDIRECT("2:"&LEN(A2)+1)))*100-ROW(INDIRECT("2:"&LEN(A2)+1))),2)
复制代码
第二版,118字符,各种优化,对于我也只能到这一步了,强行挤到120以内:

  1. =MOD(MIN(MMULT(-(MID(A2&A2,ROW($1:$99),99)<=MID(A2&A2&REPT("z",99),COLUMN(A:CU),99)),ROW(1:99))/1%+ROW($1:$99))-1,100)
复制代码
————————————————————————————————————————————————————

第一次答竞赛的VBA,也不知道是否符合规则。
原来最开始写了一小段,运行个1万字符的,花了两分钟,下面这个不会了:
  1. Public Function MinRot(ByVal sStr As String) As Long
  2.     Dim t#
  3.     Dim arr(1 To 100000), brr(1 To 100000), drr
  4.     ReDim crr(1 To 100000)
  5.     t = Timer
  6.     sLen = Len(sStr)
  7.     sStr1 = sStr & sStr
  8.     strCmp = sStr
  9.     For i = 97 To 122
  10.         strChr1 = Chr(i) '从a到z查找,看字符串中含有的最小字符
  11.         iNum = InStr(strCmp, strChr1)
  12.         If iNum > 0 Then Exit For   '找到最小字符strChr1,记录下此字符第一次出现的位置iNum
  13.     Next
  14.     arr(1) = iNum: brr(1) = Asc(Mid(sStr1, arr(1) + 1, 1)): crr(1) = brr(1) - i
  15.     For k = 2 To 100000
  16.         arr(k) = InStr(arr(k - 1) + 1, sStr, strChr1)
  17.         If arr(k) = 0 Then Exit For
  18.         brr(k) = Asc(Mid(sStr1, arr(k) + 1, 1))
  19.         crr(k) = brr(k) - i
  20.     Next
  21.     ReDim Preserve crr(1 To k - 1)
  22.     iMin = Application.Min(crr)
  23.     Set d = CreateObject("Scripting.Dictionary")
  24.     For l = 1 To k - 1
  25.         If crr(l) = iMin Then
  26.             d(arr(l)) = ""
  27.         End If
  28.     Next l
  29.     drr = d.keys
  30.     For n = 0 To UBound(drr)
  31.         strTmp = Mid(sStr1, drr(n), sLen)
  32.         If strCmp > strTmp Then
  33.             strCmp = strTmp
  34.         End If
  35.     Next n
  36.     MinRot = InStr(sStr1, strCmp) - 1
  37. 结束:
  38.     t = Timer - t
  39.     Debug.Print "ID: " & "cleverzhzhf"
  40.     Debug.Print "Answer is: " & MinRot
  41.     Debug.Print "Time used: " & Format(t, "0.000s")
  42. End Function
复制代码

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2013-11-5 17:12 | 显示全部楼层
本帖最后由 gufengaoyue 于 2013-11-13 19:07 编辑

Option Explicit
Function MinRot(ByVal sStr As String) As Long
    Dim t#
    t = Timer
    '……
Dim i&, a&, Tmp$, Mx$, Mn&, s&, Sym$, LongStr$
If Len(Replace(sStr, Left(sStr, 1), "")) = 0 Then Mn = 0: GoTo KO
If Len(Replace(sStr, Left(sStr, 2), "")) = 0 Then
    If Mid(sStr, 1, 1) < Mid(sStr, 2, 1) Then Mn = 0 Else Mn = 1
    GoTo KO
End If
Mx = String(Len(sStr), "z"): LongStr = sStr & sStr
For a = 1 To 26
    Mn = InStr(1, sStr, Chr(96 + a))
    If Mn > 0 Then
        Sym = Chr(a + 96)
        For i = 1 To Len(sStr)
            s = InStr(i, sStr, Sym)
            If s = 0 Then GoTo KO
            Tmp = Mid(LongStr, s, Len(sStr))
            If Mx > Tmp Then Mx = Tmp: Mn = s - 1
            i = s + 1
        Next
    GoTo KO
    End If
Next
KO:
MinRot = Mn
    t = Timer - t
    Debug.Print "ID: " & "<gufengaoyue>"
    Debug.Print "Answer is: " & MinRot
    Debug.Print "Time used: " & Format(t, "0.000s")
End Function

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2013-11-7 12:54 | 显示全部楼层

不知道题意有没有理解

=MATCH(,MMULT(N(MID(A2,ROW($1:$99),99)>MID(REPT(A2,99),COLUMN(A:CU),99)),ROW(1:99)^0),-1)-1

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2013-11-7 20:12 | 显示全部楼层
本帖最后由 jsxjd 于 2013-11-8 17:59 编辑

第一题 函数:

  1. Function MinRot(ByVal sStr As String) As Long
  2.     Dim t#
  3.     t = Timer
  4.     '……
  5.     Application.Volatile (True)
  6.     Dim b() As Byte, B1 As Byte, B2 As Byte, i&, j&, n&
  7.     n = Len(sStr): b = StrConv(sStr, vbFromUnicode)
  8.     For i = 1 To n - 1 'MinRot 的初始值为 0
  9.         If b(i) < b(i - 1) Then  '如果后一个字符不比前一个字符小,后一字符为起点的字符串不可能成为唯一的最小串
  10.             '当后一字符比前一字符小时,依次比较 B(i)/B(MinRot),B(i+1)/B(MinRot+1),... 比较长度为 n
  11.             '如果是循环串,比较时会穿透 i 这个位置,下面的 For 结束后 j 的值为n,程序就结束了
  12.             For j = 0 To n - 1
  13.                 B1 = b((MinRot + j) Mod n): B2 = b((i + j) Mod n)
  14.                 If B1 <> B2 Then '比较时出现不等的情况,确定 i 合理的递增量为 (i - MinRot) 的整倍数,这样可以克服局部循环串的问题
  15.                     i = i + (j \ (i - MinRot)) * (i - MinRot) ' 后面 Next i 时 i 还会自动增 1 进行下轮
  16.                     If B1 > B2 Then MinRot = i '获得新最小串的位置 ,如果存在局部循环串,这个位置会越过局部循环串
  17.                     Exit For
  18.                 End If
  19.             Next
  20.             If j >= n - 1 Then Exit For
  21.         End If
  22.     Next
  23.    
  24.     t = Timer - t
  25.     Debug.Print "ID: " & "<jsxjd>", n
  26.     Debug.Print "Answer is: " & MinRot
  27.     Debug.Print "Time used: " & Format(t, "0.000s")
  28. End Function
复制代码
第二题:
  1. =MOD(MIN(MMULT(N(MID(REPT(A2,99),ROW($1:$99),99)>MID(A2&A2,COLUMN(A:CU),99)),ROW($1:$99)^0)/1%+ROW($1:$99)),100)-1
复制代码
考虑到生成系列 1 的行号在下拉时可以不固定,简化为 112 Chars
  1. =MOD(MIN(MMULT(N(MID(REPT(A2,99),ROW($1:$99),99)>MID(A2&A2,COLUMN(A:CU),99)),ROW(1:99)^0)/1%+ROW($1:$99)),100)-1
复制代码
很奇怪,Function 代码为什么重复显示?

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2013-11-10 20:04 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
  1. =MATCH(0,MMULT(N(RIGHT(A4,LEN(A4)-ROW(INDIRECT("1:"&LEN(A4))))&MID(A4,1,ROW(INDIRECT("1:"&LEN(A4))))>TRANSPOSE(RIGHT(A4,LEN(A4)-ROW(INDIRECT("1:"&LEN(A4))))&MID(A4,1,ROW(INDIRECT("1:"&LEN(A4)))))),1^ROW(INDIRECT("1:"&LEN(A4)))),)
复制代码
数组公式

评分

1

查看全部评分

您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

关闭

最新热点上一条 /1 下一条

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-4-25 19:28 , Processed in 0.055753 second(s), 21 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表