考虑到多个条件,可以将此代码用于循环简化为查找重复项吗?

问题描述

在这里已摘录了一些代码,只是显示了相关的位:

void CImportOCLMAssignmentHistoryDlg::SetButtonStates()
{
    {
        // Don't allow import into the same assignment more than once.
        CByteArray aryImport;
        aryImport.SetSize(15);
        aryImport[0] = m_iImportOCLMHost;
        aryImport[1] = m_iImportOCLMCohost;
        aryImport[2] = m_iImportOCLMChairman;
        aryImport[3] = m_iImportOCLMOpenPrayer;
        aryImport[4] = m_iImportOCLMClosePrayer;
        aryImport[5] = m_iImportOCLMConductorCBS;
        aryImport[6] = m_iImportOCLMReaderCBS;
        aryImport[7] = m_iImportPTHost;
        aryImport[8] = m_iImportPTCohost;
        aryImport[9] = m_iImportPTChairman;
        aryImport[10] = m_iImportPTHospitality;
        aryImport[11] = m_iImportWTConductor;
        aryImport[12] = m_iImportWTReader;
        aryImport[13] = m_iImportPTSpeaker; // AJT v17.0.8
        aryImport[14] = m_iImportPTTheme;   // AJT v17.0.8

        coptionsDlg dlgOptions;
        REPORT_MODE_E eMode = dlgOptions.GetReportMode();
        bool bDuplicateAssignment = false;

        if (eMode == MODE_MEETING)
        {
            // The index values can't be duplicated within each meeting
            // Midweek 0 to 6
            // Weekend 7 to 14

            // Midweek
            for (int iAssignment = 0; iAssignment < 7; iAssignment++)
            {
                if (aryImport[iAssignment] != (BYTE)-1)
                {
                    for (int iAssignment2 = iAssignment + 1; iAssignment2 < 7; iAssignment2++)
                    {
                        if (aryImport[iAssignment2] == aryImport[iAssignment])
                        {
                            bDuplicateAssignment = true;
                            break;
                        }
                    }
                    if (bDuplicateAssignment)
                        break;
                }
            }

            if (!bDuplicateAssignment)
            {
                // Weekend
                for (int iAssignment = 7; iAssignment < aryImport.GetSize(); iAssignment++)
                {
                    if (aryImport[iAssignment] != (BYTE)-1)
                    {
                        for (int iAssignment2 = iAssignment + 1; iAssignment2 < aryImport.GetSize(); iAssignment2++)
                        {
                            if (aryImport[iAssignment2] == aryImport[iAssignment])
                            {
                                bDuplicateAssignment = true;
                                break;
                            }
                        }
                        if (bDuplicateAssignment)
                            break;
                    }
                }
            }
        }
        else
        {
            // The index values can't be duplicated anywhere in the array
            for (int iAssignment = 0; iAssignment < aryImport.GetSize(); iAssignment++)
            {
                if (aryImport[iAssignment] != (BYTE)-1)
                {
                    for (int iAssignment2 = iAssignment + 1; iAssignment2 < aryImport.GetSize(); iAssignment2++)
                    {
                        if (aryImport[iAssignment2] == aryImport[iAssignment])
                        {
                            bDuplicateAssignment = true;
                            break;
                        }
                    }
                    if (bDuplicateAssignment)
                        break;
                }
            }
        }

        if (bDuplicateAssignment)
            m_btnImport.EnableWindow(FALSE);
        else
            m_btnImport.EnableWindow(TRUE);
    }
}

代码正常运行。我只是想知道是否可以在不使可读性过度复杂的情况下进行简化。 无需评论我使用文字整数而不是#defineenum值的情况。我知道这种改善。这主要是我寻找重复项的方式。可以简化吗?

解决方法

您可以使用位图来检查重复项,而不是通过数组进行两次嵌套传递:

bool CImportOCLMAssignmentHistoryDlg::DetectDuplicateAssignment(CByteArray &aryImport,INT_PTR iMin,INT_PTR iMax)
{
  std::vector<bool> found(256);
  for (INT_PTR iAssignment = iMin; iAssignment < iMax; iAssignment++)
  {
    auto value = aryImport[iAssignment];
    if (value != (BYTE)-1)
    {
      if (found[value])
        return true;
      found[value] = true;
    }
  }
  return false;
}

要使其更加C ++,请使用std::vector<bool> found(256);而不是C样式的数组;还节省了空间。

,

我现在已经这样做了:

void CImportOCLMAssignmentHistoryDlg::SetButtonStates()
{
    {
        // Don't allow import into the same assignment more than once.
        CByteArray aryImport;
        aryImport.SetSize(15);
        aryImport[0] = m_iImportOCLMHost;
        aryImport[1] = m_iImportOCLMCohost;
        aryImport[2] = m_iImportOCLMChairman;
        aryImport[3] = m_iImportOCLMOpenPrayer;
        aryImport[4] = m_iImportOCLMClosePrayer;
        aryImport[5] = m_iImportOCLMConductorCBS;
        aryImport[6] = m_iImportOCLMReaderCBS;
        aryImport[7] = m_iImportPTHost;
        aryImport[8] = m_iImportPTCohost;
        aryImport[9] = m_iImportPTChairman;
        aryImport[10] = m_iImportPTHospitality;
        aryImport[11] = m_iImportWTConductor;
        aryImport[12] = m_iImportWTReader;
        aryImport[13] = m_iImportPTSpeaker; // AJT v17.0.8
        aryImport[14] = m_iImportPTTheme;   // AJT v17.0.8

        COptionsDlg dlgOptions;
        REPORT_MODE_E eMode = dlgOptions.GetReportMode();
        bool bDuplicateAssignment = false;

        if (eMode == MODE_MEETING)
        {
            // The index values can't be duplicated within each meeting
            // Midweek 0 to 6
            // Weekend 7 to 14

            // Midweek
            bDuplicateAssignment = DetectDuplicateAssignment(aryImport,7);

            if (!bDuplicateAssignment)
            {
                // Weekend
                bDuplicateAssignment = DetectDuplicateAssignment(aryImport,7,aryImport.GetSize());
            }
        }
        else
        {
            // The index values can't be duplicated anywhere in the array
            bDuplicateAssignment = DetectDuplicateAssignment(aryImport,aryImport.GetSize());
        }

        if (bDuplicateAssignment)
            m_btnImport.EnableWindow(FALSE);
        else
            m_btnImport.EnableWindow(TRUE);
    }
}

bool CImportOCLMAssignmentHistoryDlg::DetectDuplicateAssignment(CByteArray &aryImport,INT_PTR iMax)
{
    bool bDuplicateAssignment = false;

    for (INT_PTR iAssignment = iMin; iAssignment < iMax; iAssignment++)
    {
        if (aryImport[iAssignment] != (BYTE)-1)
        {
            for (INT_PTR iAssignment2 = iAssignment + 1; iAssignment2 < iMax; iAssignment2++)
            {
                if (aryImport[iAssignment2] == aryImport[iAssignment])
                {
                    bDuplicateAssignment = true;
                    break;
                }
            }
            if (bDuplicateAssignment)
                break;
        }
    }

    return bDuplicateAssignment;
}

如果有人有其他选择,请告诉我。谢谢。