如何使用最少的字符串删除次数将字符串转换为回文?

时间:2015-08-08 14:20:21

标签: string algorithm

假设字符串是" anuja",输出应为2,因为如果我删除字符' u'并且' n',给定的字符串变成回文。因此输出应该是最小删除次数。 更多例子:输入字符串:" ababa" 输出:0(无需移除) 输入字符串:" abcdba" 输出:1(删除' c'或' d') 请解释算法。

2 个答案:

答案 0 :(得分:13)

dp[i, i] = 0 for all i (every single character is a palindrome) 。我们有:

dp[i, j]

要查找a[i] == a[j],请考虑使用随机字符串。我们有两种可能性:

  1. 第一个和最后一个字符相等:[i+1, j-1]。在这种情况下,我们可以减少问题,找到需要删除的最小字符数,以使子串a[i] != a[j]成为回文。

  2. 第一个和最后一个字符不相等:dp[i, j] = dp[i + 1, j - 1] # if a[i] == a[j] min(dp[i + 1, j], dp[i, j - 1]) + 1 # otherwise 。在这种情况下,我们需要删除其中一个。我们将删除导致我们找到更好解决方案的内容。

  3. 所以我们有:

    anuja

    | 1 2 3 4 5 ------------- 1 | 0 1 2 2 2 2 | 0 1 2 3 3 | 0 1 2 4 | 0 1 5 | 0 为例。我们得到:

    dp[1, n]

    请注意,矩阵从主对角线开始计算并按顺序继续向上,对角线平行于主对角线。答案是using System; using System.Collections.Generic; using System.Drawing; using System.IO; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; namespace WindowsFormsApplication6 { public class Helper { private const uint ILD_TRANSPARENT = 0x00000001; private const uint SHGFI_SYSICONINDEX = 0x000004000; private const uint SHGFI_ICON = 0x000000100; public static readonly int MaxEntitiesCount = 80; public static void GetDirectories(string path, List<Image> col, IconSizeType sizeType, Size itemSize) { DirectoryInfo dirInfo = new DirectoryInfo(path); DirectoryInfo[] dirs = dirInfo.GetDirectories("*", SearchOption.TopDirectoryOnly); for (int i = 0; i < dirs.Length && i < MaxEntitiesCount; i++) { DirectoryInfo subDirInfo = dirs[i]; if (!CheckAccess(subDirInfo) || !MatchFilter(subDirInfo.Attributes)) { continue; } col.Add(GetFileImage(subDirInfo.FullName, sizeType, itemSize)); } } public static bool CheckAccess(DirectoryInfo info) { bool isOk = false; try { var secInfo = info.GetAccessControl(); isOk = true; } catch { } return isOk; } public static bool MatchFilter(FileAttributes attributes) { return (attributes & (FileAttributes.Hidden | FileAttributes.System)) == 0; } public static Image GetFileImage(string path, IconSizeType sizeType, Size itemSize) { return IconToBitmap(GetFileIcon(path, sizeType, itemSize), sizeType, itemSize); } public static Image IconToBitmap(Icon ico, IconSizeType sizeType, Size itemSize) { if (ico == null) { return new Bitmap(itemSize.Width, itemSize.Height); } return ico.ToBitmap(); } public static Icon GetFileIcon(string path, IconSizeType sizeType, Size itemSize) { SHFILEINFO shinfo = new SHFILEINFO(); IntPtr retVal = SHGetFileInfo(path, 0, ref shinfo, (uint)Marshal.SizeOf(shinfo), (int)(SHGFI_SYSICONINDEX | SHGFI_ICON)); int iconIndex = shinfo.iIcon; IImageList iImageList = (IImageList)GetSystemImageListHandle(sizeType); IntPtr hIcon = IntPtr.Zero; if (iImageList != null) { iImageList.GetIcon(iconIndex, (int)ILD_TRANSPARENT, ref hIcon); } Icon icon = null; if (hIcon != IntPtr.Zero) { icon = Icon.FromHandle(hIcon).Clone() as Icon; DestroyIcon(shinfo.hIcon); } return icon; } private static IImageList GetSystemImageListHandle(IconSizeType sizeType) { IImageList iImageList = null; Guid imageListGuid = new Guid("46EB5926-582E-4017-9FDF-E8998DAA0950"); int ret = SHGetImageList((int)sizeType, ref imageListGuid, ref iImageList); return iImageList; } [DllImport("shell32.dll", CharSet = CharSet.Auto)] private static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbFileInfo, uint uFlags); [DllImport("shell32.dll", EntryPoint = "#727")] private static extern int SHGetImageList(int iImageList, ref Guid riid, ref IImageList ppv); [DllImport("user32.dll", SetLastError = true)] private static extern bool DestroyIcon(IntPtr hIcon); public enum IconSizeType { Medium = 0x0, Small = 0x1, Large = 0x2, ExtraLarge = 0x4 } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] private struct SHFILEINFO { public IntPtr hIcon; public int iIcon; public uint dwAttributes; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string szDisplayName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)] public string szTypeName; } [ComImport, Guid("46EB5926-582E-4017-9FDF-E8998DAA0950"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] private interface IImageList { [PreserveSig] int Add(IntPtr hbmImage, IntPtr hbmMask, ref int pi); [PreserveSig] int ReplaceIcon(int i, IntPtr hicon, ref int pi); [PreserveSig] int SetOverlayImage(int iImage, int iOverlay); [PreserveSig] int Replace(int i, IntPtr hbmImage, IntPtr hbmMask); [PreserveSig] int AddMasked(IntPtr hbmImage, int crMask, ref int pi); [PreserveSig] int Draw(ref IMAGELISTDRAWPARAMS pimldp); [PreserveSig] int Remove(int i); [PreserveSig] int GetIcon(int i, int flags, ref IntPtr picon); [PreserveSig] int GetImageInfo(int i, ref IMAGEINFO pImageInfo); [PreserveSig] int Copy(int iDst, IImageList punkSrc, int iSrc, int uFlags); [PreserveSig] int Merge(int i1, IImageList punk2, int i2, int dx, int dy, ref Guid riid, ref IntPtr ppv); [PreserveSig] int Clone(ref Guid riid, ref IntPtr ppv); [PreserveSig] int GetImageRect(int i, ref RECT prc); [PreserveSig] int GetIconSize(ref int cx, ref int cy); [PreserveSig] int SetIconSize(int cx, int cy); [PreserveSig] int GetImageCount(ref int pi); [PreserveSig] int SetImageCount(int uNewCount); [PreserveSig] int SetBkColor(int clrBk, ref int pclr); [PreserveSig] int GetBkColor(ref int pclr); [PreserveSig] int BeginDrag(int iTrack, int dxHotspot, int dyHotspot); [PreserveSig] int EndDrag(); [PreserveSig] int DragEnter(IntPtr hwndLock, int x, int y); [PreserveSig] int DragLeave(IntPtr hwndLock); [PreserveSig] int DragMove(int x, int y); [PreserveSig] int SetDragCursorImage(ref IImageList punk, int iDrag, int dxHotspot, int dyHotspot); [PreserveSig] int DragShowNolock(int fShow); [PreserveSig] int GetDragImage(ref POINT ppt, ref POINT pptHotspot, ref Guid riid, ref IntPtr ppv); [PreserveSig] int GetItemFlags(int i, ref int dwFlags); [PreserveSig] int GetOverlayImage(int iOverlay, ref int piIndex); } ; [StructLayout(LayoutKind.Sequential)] private struct IMAGELISTDRAWPARAMS { public int cbSize; public IntPtr himl; public int i; public IntPtr hdcDst; public int x; public int y; public int cx; public int cy; public int xBitmap; public int yBitmap; public int rgbBk; public int rgbFg; public int fStyle; public int dwRop; public int fState; public int Frame; public int crEffect; } [StructLayout(LayoutKind.Sequential)] private struct IMAGEINFO { public IntPtr hbmImage; public IntPtr hbmMask; public int Unused1; public int Unused2; public RECT rcImage; } [StructLayout(LayoutKind.Sequential)] public struct RECT { public int Left, Top, Right, Bottom; public RECT(int l, int t, int r, int b) { Left = l; Top = t; Right = r; Bottom = b; } public RECT(Rectangle r) { Left = r.Left; Top = r.Top; Right = r.Right; Bottom = r.Bottom; } public Rectangle ToRectangle() { return Rectangle.FromLTRB(Left, Top, Right, Bottom); } public void Inflate(int width, int height) { Left -= width; Top -= height; Right += width; Bottom += height; } public override string ToString() { return string.Format("x:{0},y:{1},width:{2},height:{3}", Left, Top, Right - Left, Bottom - Top); } } [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)] public struct POINT { public int X, Y; public POINT(int x, int y) { this.X = x; this.Y = y; } public POINT(Point pt) { this.X = pt.X; this.Y = pt.Y; } public Point ToPoint() { return new Point(X, Y); } } } }

    这类似于Levenshtein distance,但它只考虑删除。

答案 1 :(得分:1)

您可以测量从字符串到其反向的编辑距离(levenshtein距离)(忽略替换)。期望的值将是该值的一半。

此问题与UVA 10739类似。这是一个example implementation

示例实现(适合您的情况)可以是:

string P, Q;
getline(cin, P);
Q = string(P.rbegin(), P.rend());
int p = P.size(), q = Q.size();

for(int i=0; i<=p; i++) { T[i][0] = i; }
for(int i=0; i<=q; i++) { T[0][i] = i; }

for(int i=1; i<=p; i++) {
    for(int j=1; j<=q; j++) {
        if (P[i-1] == Q[j-1])
            T[i][j] = T[i-1][j-1];
        else
            T[i][j] = min(T[i-1][j], T[i][j-1]) + 1;
    }
}

cout << "Case " << tt << ": " << T[p][q]/2 << endl;