Los eventos de entrada no están garantizados en orden cronológico, por lo que es necesario ordenarlos primero según la marca de tiempo.
Se ordenan los eventos de menor a mayor marca de tiempo. Para marcas iguales, los eventos de desconexión se procesan antes que los mensajes, ya que los cambios de estado deben ocurrir antes de los eventos de mensaje según el enunciado.
A continuación, se simula el procesamiento:
- Eventos de desconexión: Se utiliza un arreglo para rastrear cuándo cada usuario vuelve a estar en línea (60 segundos después). Si la marca de tiempo actual es mayor o igual a este valor, el usuario se considera en línea.
- Eventos de mensaje: Se incrementa el contador de menciones para los usuarios pertinentes.
Para el análisis de menciones en el texto del mensaje:
string& texto_mencion = eventos[i][2]; // Ejemplo de acceso al contenido
Si la mención es "@all", se incrementa el contador para todos los usuarios. Si es "@here", se incrementa solo para usuarios en línea. Para menciones de IDs específicos, se extraen los números del texto.
else { // Mención de ID específico
int id_acumulado = 0;
for (int j = 0; j < texto_mencion.size(); j++) {
if (isdigit(texto_mencion[j]))
id_acumulado = id_acumulado * 10 + (texto_mencion[j] - '0');
if (j + 1 == texto_mencion.size() || texto_mencion[j + 1] == ' ') {
contadores[id_acumulado]++;
id_acumulado = 0;
}
}
}
isdigit verifica si un carácter es un dígito decimal. Dado que el número de usuarios puede ser hasta 100, se acumulan dígitos para manejar IDs como "id12".
Implementación completa en C++ con lógica reestructurada:
class Solucion {
public:
vector<int> contarMenciones(int totalUsuarios, vector<vector>>& listaEventos) {
vector<int> menciones(totalUsuarios, 0);
vector<int> proximaOnline(totalUsuarios, 0);
// Función de comparación para ordenar eventos
auto compararEventos = [](const vector<string>& evt1, const vector<string>& evt2) {
int tiempo1 = stoi(evt1[1]);
int tiempo2 = stoi(evt2[1]);
if (tiempo1 != tiempo2) return tiempo1 < tiempo2;
// Para tiempos iguales, "OFFLINE" tiene prioridad sobre "MESSAGE" por orden lexicográfico
return evt1[0] > evt2[0];
};
sort(listaEventos.begin(), listaEventos.end(), compararEventos);
for (const auto& eventoActual : listaEventos) {
int tiempoActual = stoi(eventoActual[1]);
const string& contenidoMencion = eventoActual[2];
if (eventoActual[0][0] == 'O') { // Evento de desconexión
int usuarioID = stoi(contenidoMencion);
proximaOnline[usuarioID] = tiempoActual + 60;
}
else if (contenidoMencion[0] == 'A') { // Mención @all
for (int k = 0; k < totalUsuarios; k++)
menciones[k]++;
}
else if (contenidoMencion[0] == 'H') { // Mención @here
for (int k = 0; k < totalUsuarios; k++) {
if (tiempoActual >= proximaOnline[k])
menciones[k]++;
}
}
else { // Mención de IDs específicos
int idNumerico = 0;
for (size_t pos = 0; pos < contenidoMencion.size(); pos++) {
if (isdigit(contenidoMencion[pos]))
idNumerico = idNumerico * 10 + (contenidoMencion[pos] - '0');
if (pos + 1 == contenidoMencion.size() || contenidoMencion[pos + 1] == ' ') {
menciones[idNumerico]++;
idNumerico = 0;
}
}
}
}
return menciones;
}
};</string></string></int></int></vector></int>